<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/all.min.css" integrity="sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"tallgy.gitee.io","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":false,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>
<meta name="description" content="只是一个知识的搬运工">
<meta property="og:type" content="website">
<meta property="og:title" content="tallgy&#39;s blog">
<meta property="og:url" content="http://tallgy.gitee.io/page/9/index.html">
<meta property="og:site_name" content="tallgy&#39;s blog">
<meta property="og:description" content="只是一个知识的搬运工">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="tallgy">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="http://tallgy.gitee.io/page/9/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"page/9/index.html","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>tallgy's blog</title>
  




  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">tallgy's blog</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>







</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-overview-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">tallgy</p>
  <div class="site-description" itemprop="description">只是一个知识的搬运工</div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">107</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">32</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">74</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner index posts-expand">

    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/29/Vue/Vue2-%E6%95%99%E7%A8%8B/Vue2-%E6%95%99%E7%A8%8B-%E8%BF%87%E6%B8%A1%E5%92%8C%E5%8A%A8%E7%94%BB/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/29/Vue/Vue2-%E6%95%99%E7%A8%8B/Vue2-%E6%95%99%E7%A8%8B-%E8%BF%87%E6%B8%A1%E5%92%8C%E5%8A%A8%E7%94%BB/" class="post-title-link" itemprop="url">Vue-使用-过渡和动画</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-29 23:15:25" itemprop="dateCreated datePublished" datetime="2021-10-29T23:15:25+08:00">2021-10-29</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/" itemprop="url" rel="index"><span itemprop="name">Vue</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/Vue2%E6%96%87%E6%A1%A3/" itemprop="url" rel="index"><span itemprop="name">Vue2文档</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="过渡和动画"><a href="#过渡和动画" class="headerlink" title="过渡和动画"></a>过渡和动画</h1><h2 id="进入-离开和列表转换"><a href="#进入-离开和列表转换" class="headerlink" title="进入/离开和列表转换"></a>进入/离开和列表转换</h2><p>​        Vue提供了多种方法在DOM中的过渡效果</p>
<ul>
<li>自动为CSS过渡和动画应用类</li>
<li>集成第三方CSS动画库，如 Animate.css</li>
<li>在过渡钩子期间使用 JavaScript 直接操作 DOM</li>
<li>集成第三方JavaScript动画库，例如 Velocity.js</li>
</ul>
<h3 id="过渡单个元素-组件"><a href="#过渡单个元素-组件" class="headerlink" title="过渡单个元素/组件"></a>过渡单个元素/组件</h3><p>​        Vue 提供了一个<code>transition</code>包装组件，允许您在以下上下文中为任何元素或组件添加进入/离开转换：</p>
<ul>
<li>条件渲染（使用<code>v-if</code>）</li>
<li>条件显示（使用<code>v-show</code>）</li>
<li>动态组件</li>
<li>组件根节点</li>
</ul>
<p>​        在这里我直接复制官网的例子，并加以一个简单的说明，首先，对于transition来说，需要的是一个根组件（根元素），对于存在多个根组件的，便会只渲染一个，其次，对于不是非根元素进行的渲染显示不会有效果。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;demo&quot;&gt;</span><br><span class="line">  &lt;button v-on:click=&quot;show = !show&quot;&gt;</span><br><span class="line">    Toggle</span><br><span class="line">  &lt;/button&gt;</span><br><span class="line">  &lt;transition name=&quot;fade&quot;&gt;</span><br><span class="line">    &lt;p v-if=&quot;show&quot;&gt;hello&lt;/p&gt;</span><br><span class="line">  &lt;/transition&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">new Vue(&#123;</span><br><span class="line">  el: &#x27;#demo&#x27;,</span><br><span class="line">  data: &#123;</span><br><span class="line">    show: true</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">.fade-enter-active, .fade-leave-active &#123;</span><br><span class="line">  transition: opacity .5s;</span><br><span class="line">&#125;</span><br><span class="line">.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ &#123;</span><br><span class="line">  opacity: 0;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>当<code>transition</code>插入或删除包裹在组件中的元素时，会发生以下情况：</p>
<ol>
<li>Vue 会自动嗅探目标元素是否应用了 CSS 过渡或动画。如果是这样，CSS 过渡类将在适当的时间添加/删除。</li>
<li>如果转换组件提供了<a target="_blank" rel="noopener" href="https://vuejs.org/v2/guide/transitions.html#JavaScript-Hooks">JavaScript hooks</a>，这些 hooks 将在适当的时间被调用。</li>
<li>如果没有检测到 CSS 过渡/动画，也没有提供 JavaScript 钩子，插入和/或移除的 DOM 操作将在下一帧立即执行（注意：这是一个浏览器动画帧，与 Vue 的概念不同<code>nextTick</code>）。</li>
</ol>
<h4 id="过渡的类名"><a href="#过渡的类名" class="headerlink" title="过渡的类名"></a>过渡的类名</h4><p>​        在进入/离开的过程中，会有6个 class 切换</p>
<ul>
<li>v-enter<ul>
<li>进入的起始状态，在插入元素之前添加，在插入元素后移除一帧</li>
</ul>
</li>
<li>v-enter-active<ul>
<li>进入的活动状态，在整个进入阶段应用。插入元素之前添加，在过渡完成时移除。定义进入过渡的事件、延迟和缓动曲线。</li>
</ul>
</li>
<li>v-enter-to<ul>
<li>2.1.8+</li>
<li>进入的结束状态。插入元素后添加一帧（同时 v-enter 删除），在过渡完成时删除。</li>
</ul>
</li>
<li>v-leave<ul>
<li>定义离开过渡的开始状态。在离开过渡被触发时立刻生效。下一帧被移除</li>
</ul>
</li>
<li>v-leave-active<ul>
<li>定义离开过渡生效时的状态。在离开过渡立刻生效，过渡完成被移除，同 v-enter-active</li>
</ul>
</li>
<li>v-leave-to<ul>
<li>2.1.8 +</li>
<li>定义离开过渡的结束状态。离开过渡被触发后下一帧生效（同时 v-leave 被删除）。过渡完成被移除</li>
</ul>
</li>
</ul>
<p><img src="/.io//Vue2-%E6%95%99%E7%A8%8B-%E8%BF%87%E6%B8%A1%E5%92%8C%E5%8A%A8%E7%94%BB%5Cimage-20211203152116522.png" alt="image-20211203152116522"></p>
<p>​        在这些过渡的切换中，如果你使用一个没有名字的transition，则v-是这些类名的默认前缀。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition&gt;</span><br><span class="line">    &lt;p v-show=&quot;show&quot;&gt;hello&lt;/p&gt;</span><br><span class="line">&lt;/transition&gt;</span><br><span class="line"></span><br><span class="line">.v-enter-active,</span><br></pre></td></tr></table></figure>

<p>​        如果你使用了 <code>&lt;transition name=&quot;my-transition&quot;&gt;</code> ，那么 <code>v-enter</code> 会替换为 <code>my-transition-enter</code> 。</p>
<p>​        v-enter-active 和 v-leave-active 可以控制进入/离开过渡的不同的缓和曲线。</p>
<img src="/.io//image-20211203154333481.png" alt="image-20211203154333481">

<p>​        通过图示可以看出，当元素进行显示时：</p>
<ul>
<li>先插入 v-enter 和 v-enter-active， </li>
<li>然后再下一帧删除 v-enter，出现了 v-enter-to</li>
<li>然后结束了 v-enter-active 和 v-enter-to 消失。</li>
</ul>
<p>v-leave 是一样的效果。</p>
<h4 id="CSS过渡"><a href="#CSS过渡" class="headerlink" title="CSS过渡"></a>CSS过渡</h4><p>​        和普通的过渡是没有什么区别的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">.bounce-enter-active &#123;</span><br><span class="line">  animation: bounce-in .5s;</span><br><span class="line">&#125;</span><br><span class="line">.bounce-leave-active &#123;</span><br><span class="line">  animation: bounce-in .5s reverse;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@keyframes bounce-in &#123;</span><br><span class="line">  0% &#123;</span><br><span class="line">    transform: scale(0);</span><br><span class="line">  &#125;</span><br><span class="line">  50% &#123;</span><br><span class="line">    transform: scale(1.5);</span><br><span class="line">  &#125;</span><br><span class="line">  100% &#123;</span><br><span class="line">    transform: scale(1);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h4 id="自定义过渡的类名"><a href="#自定义过渡的类名" class="headerlink" title="自定义过渡的类名"></a>自定义过渡的类名</h4><p>​        我们可以通过使用以下的属性来自定义过渡的类名。并且他们的优先级会高于普通的类名。因此对于使用其他第三方css库十分的有用。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">enter-class</span><br><span class="line">enter-active-class</span><br><span class="line">enter-to-class (2.1.8+)</span><br><span class="line">leave-class</span><br><span class="line">leave-active-class</span><br><span class="line">leave-to-class (2.1.8+)</span><br></pre></td></tr></table></figure>

<p>​        这里name就是往常一样的name，然后在元素里面添加了标签，标签是 enter-xx-class，或者是 leave-xx-class 这种。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition</span><br><span class="line">name=&quot;custom-classes-transition&quot;</span><br><span class="line">enter-active-class=&quot;animated tada&quot;</span><br><span class="line">leave-active-class=&quot;animated bounceOutRight&quot;</span><br><span class="line">&gt;</span><br><span class="line">    &lt;p v-if=&quot;show&quot;&gt;hello&lt;/p&gt;</span><br><span class="line">&lt;/transition&gt;</span><br></pre></td></tr></table></figure>



<h4 id="同时使用过渡和动画"><a href="#同时使用过渡和动画" class="headerlink" title="同时使用过渡和动画"></a>同时使用过渡和动画</h4><p>​        Vue为了能知道过渡的完成，必须设置相应的事件监听器。他可以是 transitionend 或者是 animationend，如果你只是使用了其中一种，Vue可以自动识别并设置监听。</p>
<p>​        但是如果你同时使用了 transition 和 animation，那么这种情况你就需要使用 type 属性来指定Vue需要监听的类型。</p>
<p>​        如果你不指定的话，我从使用上看来他会默认监听的是时间最长的那个，就是延迟时间和运行时间加起来最大的那个。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition name=&quot;slide-fade&quot; type=&quot;transition&quot;&gt;</span><br><span class="line">    &lt;p v-if=&quot;show&quot;&gt; content &lt;/p&gt;</span><br><span class="line">&lt;/transition&gt;</span><br></pre></td></tr></table></figure>



<h4 id="显性的过渡持续时间"><a href="#显性的过渡持续时间" class="headerlink" title="显性的过渡持续时间"></a>显性的过渡持续时间</h4><p>​        2.2.0 新增</p>
<p>​        默认情况下，Vue会自动计算出过渡时间。会等待过渡效果的 transitionend 和 animationend 事件。</p>
<p>​        但是，我们可以显性的设置一个过渡的持续时间。</p>
<p>​        下面这个代码的意思就是，对于使用了 duration 设置了显性的过渡时间了的，在到达过渡的时间之后，便会直接进行过渡的结束。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition :duration=&quot;1000&quot;&gt;...&lt;/transition&gt;</span><br><span class="line"></span><br><span class="line">&lt;transition :duration=&quot;&#123; enter: 500, leave: 800 &#125;&quot;&gt;...&lt;/transition&gt;</span><br></pre></td></tr></table></figure>



<h4 id="JavaScript-钩子"><a href="#JavaScript-钩子" class="headerlink" title="JavaScript 钩子"></a>JavaScript 钩子</h4><p>​        可以在属性中声明 JavaScript 钩子。</p>
<p>​        这里我简单介绍一下 JavaScript钩子的执行时机，虽然通过名字也能够大致猜的出来意思</p>
<ul>
<li>before-enter： 简单来说就是在enter启动之前，就像是前面的 v-enter</li>
<li>enter： 就是在调用期间， v-enter-to，但是这个 JavaScript钩子 没有说版本要求，而 v-enter-to 是2.1.8以上的，所以这个应该是更像 v-enter-active 。</li>
<li>after-enter： 就是在就是结束时会进行的调用，应该接近于 animationend 或者 transitionend 这两个回调。</li>
<li>enter-cancalled： 就是在没有调用after-enter的时候就又进行了一次切换，此时就会调用 enter-cancalled 回调。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition</span><br><span class="line">  v-on:before-enter=&quot;beforeEnter&quot;</span><br><span class="line">  v-on:enter=&quot;enter&quot;</span><br><span class="line">  v-on:after-enter=&quot;afterEnter&quot;</span><br><span class="line">  v-on:enter-cancelled=&quot;enterCancelled&quot;</span><br><span class="line"></span><br><span class="line">  v-on:before-leave=&quot;beforeLeave&quot;</span><br><span class="line">  v-on:leave=&quot;leave&quot;</span><br><span class="line">  v-on:after-leave=&quot;afterLeave&quot;</span><br><span class="line">  v-on:leave-cancelled=&quot;leaveCancelled&quot;</span><br><span class="line">&gt;</span><br><span class="line">  &lt;!-- ... --&gt;</span><br><span class="line">&lt;/transition&gt;</span><br></pre></td></tr></table></figure>

<p>​        这里需要注意，</p>
<ul>
<li>当只用 JavaScript 过渡的时候，<strong>在 <code>enter</code> 和 <code>leave</code> 中必须使用 <code>done</code> 进行回调</strong>。否则，它们将被同步调用，过渡会立即完成。<ul>
<li>这个我没有仔细使用过函数进行动画的过渡，而是进行一些其他的操作，但是这里 done的回调是必须的。因为我们可以看到如果不使用done函数，那么便不会调用 after-enter 来结束，所以这个done函数更像是 生成器函数的 next 一样。</li>
<li>这里我使用了css进行过渡，然后JavaScript进行钩子的调用，发现css的过渡没有出现效果，直接只能使用钩子的调用了。就算是使用自定义过渡类名属性 enter-class 这些也没有效果。</li>
</ul>
</li>
<li>推荐对于仅使用 JavaScript 过渡的元素添加 <code>v-bind:css=&quot;false&quot;</code>，Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。</li>
<li>leaveCancelled 只能用于 v-show 中。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line">// ...</span><br><span class="line">methods: &#123;</span><br><span class="line">  // --------</span><br><span class="line">  // 进入中</span><br><span class="line">  // --------</span><br><span class="line"></span><br><span class="line">  beforeEnter: function (el) &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;,</span><br><span class="line">  // 当与 CSS 结合使用时</span><br><span class="line">  // 回调函数 done 是可选的</span><br><span class="line">  enter: function (el, done) &#123;</span><br><span class="line">    // ...</span><br><span class="line">    done()</span><br><span class="line">  &#125;,</span><br><span class="line">  afterEnter: function (el) &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;,</span><br><span class="line">  enterCancelled: function (el) &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  // --------</span><br><span class="line">  // 离开时</span><br><span class="line">  // --------</span><br><span class="line"></span><br><span class="line">  beforeLeave: function (el) &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;,</span><br><span class="line">  // 当与 CSS 结合使用时</span><br><span class="line">  // 回调函数 done 是可选的</span><br><span class="line">  leave: function (el, done) &#123;</span><br><span class="line">    // ...</span><br><span class="line">    done()</span><br><span class="line">  &#125;,</span><br><span class="line">  afterLeave: function (el) &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;,</span><br><span class="line">  // leaveCancelled 只用于 v-show 中</span><br><span class="line">  leaveCancelled: function (el) &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="初始渲染的过渡"><a href="#初始渲染的过渡" class="headerlink" title="初始渲染的过渡"></a>初始渲染的过渡</h3><p>​        通过使用 appear 属性设置节点初始渲染的过渡</p>
<p>​        简单来说就是会在开始的时候有一个过渡的效果。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition appear&gt;</span><br></pre></td></tr></table></figure>

<p>​    可以自定义 css 类名</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition</span><br><span class="line">  appear</span><br><span class="line">  appear-class=&quot;custom-appear-class&quot;</span><br><span class="line">  appear-to-class=&quot;custom-appear-to-class&quot; (2.1.8+)</span><br><span class="line">  appear-active-class=&quot;custom-appear-active-class&quot;</span><br><span class="line">&gt;</span><br></pre></td></tr></table></figure>

<p>​    自定义JavaScript 钩子</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition</span><br><span class="line">  appear</span><br><span class="line">  v-on:before-appear=&quot;customBeforeAppearHook&quot;</span><br><span class="line">  v-on:appear=&quot;customAppearHook&quot;</span><br><span class="line">  v-on:after-appear=&quot;customAfterAppearHook&quot;</span><br><span class="line">  v-on:appear-cancelled=&quot;customAppearCancelledHook&quot;</span><br><span class="line">&gt;</span><br></pre></td></tr></table></figure>

<p>​        在上面的例子中，无论是使用 appear attribute 还是使用 v-on:appear 钩子都会生成初始渲染的过渡。</p>
<h3 id="多个元素的过渡"><a href="#多个元素的过渡" class="headerlink" title="多个元素的过渡"></a>多个元素的过渡</h3><p>​        对于原生的标签，可以使用 v-if / v-else 进行过渡。</p>
<blockquote>
<p>当有<strong>相同标签名</strong>的元素切换时，需要通过 <code>key</code> attribute 设置唯一的值来标记以让 Vue 区分它们，否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要，<strong>给在 <code>&lt;transition&gt;</code> 组件中的多个元素设置 key 是一个更好的实践。</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition&gt;</span><br><span class="line">  &lt;button v-if=&quot;isEditing&quot; key=&quot;save&quot;&gt;</span><br><span class="line">    Save</span><br><span class="line">  &lt;/button&gt;</span><br><span class="line">  &lt;button v-else key=&quot;edit&quot;&gt;</span><br><span class="line">    Edit</span><br><span class="line">  &lt;/button&gt;</span><br><span class="line">&lt;/transition&gt;</span><br></pre></td></tr></table></figure>

<p>​        在某些场景，也可以通过给同一个元素的key属性设置不同的状态来代替 v-if 和 v-else。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition&gt;</span><br><span class="line">  &lt;button v-bind:key=&quot;isEditing&quot;&gt;</span><br><span class="line">    &#123;&#123; isEditing ? &#x27;Save&#x27; : &#x27;Edit&#x27; &#125;&#125;</span><br><span class="line">  &lt;/button&gt;</span><br><span class="line">&lt;/transition&gt;</span><br></pre></td></tr></table></figure>



<h4 id="过渡模式"><a href="#过渡模式" class="headerlink" title="过渡模式"></a>过渡模式</h4><p>​        简单来说就是元素的切换是同步的，所以会出现占位的问题，并且当使用的是 v-if 的时候，开始会占位，但是在过渡结束之后就会出现位置消失，然后后面的元素会补充上去。</p>
<p>​        所以此时我们就需要进行处理。</p>
<p>​        解决方式一般是使用定位的形式，因为定位是脱离了文档流的，所以就不会出现这个问题了。然后此时我们再使用一个 transition 进行过渡的显示便有了效果。</p>
<p>​        当然同时生效的进入和离开的过渡不能满足所有要求，所以Vue提供了<strong>过渡模式</strong> mode</p>
<ul>
<li><code>in-out</code> ：新元素先过渡，完成后旧元素过渡离开。</li>
<li><code>out-in</code> ：旧元素先过渡，完成后新元素过渡进入。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition name=&quot;fade&quot; mode=&quot;out-in&quot;&gt;</span><br><span class="line">  &lt;!-- ... the buttons ... --&gt;</span><br><span class="line">&lt;/transition&gt;</span><br></pre></td></tr></table></figure>



<h3 id="多组件的过渡"><a href="#多组件的过渡" class="headerlink" title="多组件的过渡"></a>多组件的过渡</h3><p>​        我们可以直接使用动态组件来进行组件之间的过渡</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition name=&quot;component-fade&quot; mode=&quot;out-in&quot;&gt;</span><br><span class="line">  &lt;component v-bind:is=&quot;view&quot;&gt;&lt;/component&gt;</span><br><span class="line">&lt;/transition&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">new Vue(&#123;</span><br><span class="line">  el: &#x27;#transition-components-demo&#x27;,</span><br><span class="line">  data: &#123;</span><br><span class="line">    view: &#x27;v-a&#x27;</span><br><span class="line">  &#125;,</span><br><span class="line">  components: &#123;</span><br><span class="line">    &#x27;v-a&#x27;: &#123;</span><br><span class="line">      template: &#x27;&lt;div&gt;Component A&lt;/div&gt;&#x27;</span><br><span class="line">    &#125;,</span><br><span class="line">    &#x27;v-b&#x27;: &#123;</span><br><span class="line">      template: &#x27;&lt;div&gt;Component B&lt;/div&gt;&#x27;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<h3 id="列表过渡"><a href="#列表过渡" class="headerlink" title="列表过渡"></a>列表过渡</h3><p>​        对于使用v-for渲染时的过渡。可以使用 transition-group 组件。</p>
<p><strong>特点</strong>：</p>
<ul>
<li>transition-group 会以一个真实的元素呈现：默认为 span，也可以通过 tag 属性来更换为其他元素。</li>
<li>不能使用过渡模式。mode</li>
<li>内部元素总是需要提供一个唯一的 key 属性值</li>
<li>CSS 过渡的类 将会应用在内部元素中，而不是这个 组件/容器 本身。</li>
</ul>
<p>​        这里，首先name为list，其次使用了tag，默认不使用tag时为span，使用了tag为p，所以就是p标签进行包裹。然后内部是使用span标签进行的for循环。最后，使用transition-group，key值是必须的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition-group name=&quot;list&quot; tag=&quot;p&quot;&gt;</span><br><span class="line">	&lt;span v-for=&quot;item in items&quot; v-bind:key=&quot;item&quot; class=&quot;list-item&quot;&gt;</span><br><span class="line">		&#123;&#123; item &#125;&#125;</span><br><span class="line">	&lt;/span&gt;</span><br><span class="line">&lt;/transition-group&gt;</span><br></pre></td></tr></table></figure>



<h4 id="列表的进入-离开过渡"><a href="#列表的进入-离开过渡" class="headerlink" title="列表的进入/离开过渡"></a>列表的进入/离开过渡</h4><p>​        列表的进入/离开过渡是和以前的过渡的方式是一样的。只是过渡变成了每一个小组件了。</p>
<p>​        问题就是过渡的平滑展现，比如新增的元素，周围的元素会瞬间移动到他们新布局的位置，而不是平滑的过渡。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">.list-enter-active, .list-leave-active &#123;</span><br><span class="line">  transition: all 1s;</span><br><span class="line">&#125;</span><br><span class="line">.list-enter, .list-leave-to</span><br><span class="line">/* .list-leave-active for below version 2.1.8 */ &#123;</span><br><span class="line">  opacity: 0;</span><br><span class="line">  transform: translateY(30px);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h4 id="排序的过渡"><a href="#排序的过渡" class="headerlink" title="排序的过渡"></a>排序的过渡</h4><p>​        可以通过使用 v-move 类来实现列表的移动。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition-group name=&quot;list&quot; tag=&quot;ul&quot;&gt;</span><br><span class="line">    &lt;li v-for=&quot;(item, index) in items&quot; v-bind:key=&quot;item&quot; class=&quot;list-item&quot;&gt;</span><br><span class="line">		&#123;&#123; item &#125;&#125;</span><br><span class="line">    &lt;/li&gt;</span><br><span class="line">&lt;/transition-group&gt;</span><br><span class="line"></span><br><span class="line">.list-item &#123;</span><br><span class="line">    transition: all 1s;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">.list-enter,</span><br><span class="line">.list-leave-to &#123;</span><br><span class="line">    opacity: 0;</span><br><span class="line">    transform: translateY(30px);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        如果我对列表进行一次排序。就会发现动画的效果。</p>
<p>​    这个看起来很神奇，内部的实现，Vue 使用了一个叫 <a target="_blank" rel="noopener" href="https://aerotwist.com/blog/flip-your-animations/">FLIP</a> 简单的动画队列。</p>
<p>​        当然，前面的style样式对于增加排序时的效果都还是不错，但是对于删除来说，效果就不一样了。</p>
<p>​    于是我们对于要进行删除的元素进行了一个绝对定位。</p>
<p>​    对于为什么要使用绝对定位，那是因为当使用了绝对定位之后，那便不会在同一图层。然后此时后面的元素便会向前移动，然后再通过 transition: all .5s; 来进行一个动态的变化。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">.list-leave-active &#123;</span><br><span class="line">    position: absolute;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>需要注意的是使用 FLIP 过渡的元素不能设置为 <code>display: inline</code> 。作为替代方案，可以设置为 <code>display: inline-block</code> 或者放置于 flex 中</p>
</blockquote>
<p><strong>多维网格也可以进行过渡</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">  &lt;head&gt;</span><br><span class="line">    &lt;title&gt;List Move Transitions Sudoku Example&lt;/title&gt;</span><br><span class="line">    &lt;script src=&quot;https://unpkg.com/vue&quot;&gt;&lt;/script&gt;</span><br><span class="line">    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;./style.css&quot; /&gt;</span><br><span class="line">  &lt;/head&gt;</span><br><span class="line">  &lt;body&gt;</span><br><span class="line">    &lt;div id=&quot;sudoku-demo&quot; class=&quot;demo&quot;&gt;</span><br><span class="line">      &lt;h1&gt;Lazy Sudoku&lt;/h1&gt;</span><br><span class="line">      &lt;p&gt;Keep hitting the shuffle button until you win.&lt;/p&gt;</span><br><span class="line"></span><br><span class="line">      &lt;button @click=&quot;shuffle&quot;&gt;</span><br><span class="line">        Shuffle</span><br><span class="line">      &lt;/button&gt;</span><br><span class="line">      &lt;transition-group name=&quot;cell&quot; tag=&quot;div&quot; class=&quot;container&quot;&gt;</span><br><span class="line">        &lt;div v-for=&quot;cell in cells&quot; :key=&quot;cell.id&quot; class=&quot;cell&quot;&gt;</span><br><span class="line">          &#123;&#123; cell.number &#125;&#125;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">      &lt;/transition-group&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line"></span><br><span class="line">    &lt;script&gt;</span><br><span class="line">      new Vue(&#123;</span><br><span class="line">        el: &quot;#sudoku-demo&quot;,</span><br><span class="line">        data: &#123;</span><br><span class="line">          cells: Array.apply(null, &#123; length: 81 &#125;).map(function(_, index) &#123;</span><br><span class="line">            return &#123;</span><br><span class="line">              id: index,</span><br><span class="line">              number: (index % 9) + 1</span><br><span class="line">            &#125;;</span><br><span class="line">          &#125;)</span><br><span class="line">        &#125;,</span><br><span class="line">        methods: &#123;</span><br><span class="line">          shuffle: function() &#123;</span><br><span class="line">            this.cells = this.randomSort(this.cells);</span><br><span class="line">          &#125;,</span><br><span class="line">          randomSort(arr) &#123;</span><br><span class="line">            const res = arr.slice();</span><br><span class="line">            for (let i=0; i&lt;arr.length; i++) &#123;</span><br><span class="line">              const index = this.randomIndex();</span><br><span class="line">              [res[i], res[index]] = [res[index], res[i]];</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            return res;</span><br><span class="line">          &#125;,</span><br><span class="line">          randomIndex() &#123;</span><br><span class="line">            return Math.floor(Math.random() * this.cells.length);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;);</span><br><span class="line">    &lt;/script&gt;</span><br><span class="line">  &lt;/body&gt;</span><br><span class="line">  </span><br><span class="line">  &lt;style&gt;</span><br><span class="line">.container &#123;</span><br><span class="line">  display: flex;</span><br><span class="line">  flex-wrap: wrap;</span><br><span class="line">  width: 238px;</span><br><span class="line">  margin-top: 10px;</span><br><span class="line">&#125;</span><br><span class="line">.cell &#123;</span><br><span class="line">  display: flex;</span><br><span class="line">  justify-content: space-around;</span><br><span class="line">  align-items: center;</span><br><span class="line">  width: 25px;</span><br><span class="line">  height: 25px;</span><br><span class="line">  border: 1px solid #aaa;</span><br><span class="line">  margin-right: -1px;</span><br><span class="line">  margin-bottom: -1px;</span><br><span class="line">&#125;</span><br><span class="line">.cell:nth-child(3n) &#123;</span><br><span class="line">  margin-right: 0;</span><br><span class="line">&#125;</span><br><span class="line">.cell:nth-child(27n) &#123;</span><br><span class="line">  margin-bottom: 0;</span><br><span class="line">&#125;</span><br><span class="line">.cell-move &#123;</span><br><span class="line">  transition: transform 1s;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">  &lt;/style&gt;</span><br><span class="line">  </span><br><span class="line">&lt;/html&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h4 id="交错的过渡"><a href="#交错的过渡" class="headerlink" title="交错的过渡"></a>交错的过渡</h4><p>​        通过data属性和JavaScript的通信，可以实现列表的交错过渡。简单来说就是使用js方法进行了渲染。因为 velocity 不能访问，所以没有进行实验。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line">&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js&quot;&gt;&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;div id=&quot;staggered-list-demo&quot;&gt;</span><br><span class="line">  &lt;input v-model=&quot;query&quot;&gt;</span><br><span class="line">  &lt;transition-group</span><br><span class="line">    name=&quot;staggered-fade&quot;</span><br><span class="line">    tag=&quot;ul&quot;</span><br><span class="line">    v-bind:css=&quot;false&quot;</span><br><span class="line">    v-on:before-enter=&quot;beforeEnter&quot;</span><br><span class="line">    v-on:enter=&quot;enter&quot;</span><br><span class="line">    v-on:leave=&quot;leave&quot;</span><br><span class="line">  &gt;</span><br><span class="line">    &lt;li</span><br><span class="line">      v-for=&quot;(item, index) in computedList&quot;</span><br><span class="line">      v-bind:key=&quot;item.msg&quot;</span><br><span class="line">      v-bind:data-index=&quot;index&quot;</span><br><span class="line">    &gt;&#123;&#123; item.msg &#125;&#125;&lt;/li&gt;</span><br><span class="line">  &lt;/transition-group&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">new Vue(&#123;</span><br><span class="line">  el: &#x27;#staggered-list-demo&#x27;,</span><br><span class="line">  data: &#123;</span><br><span class="line">    query: &#x27;&#x27;,</span><br><span class="line">    list: [</span><br><span class="line">      &#123; msg: &#x27;Bruce Lee&#x27; &#125;,</span><br><span class="line">      &#123; msg: &#x27;Jackie Chan&#x27; &#125;,</span><br><span class="line">      &#123; msg: &#x27;Chuck Norris&#x27; &#125;,</span><br><span class="line">      &#123; msg: &#x27;Jet Li&#x27; &#125;,</span><br><span class="line">      &#123; msg: &#x27;Kung Fury&#x27; &#125;</span><br><span class="line">    ]</span><br><span class="line">  &#125;,</span><br><span class="line">  computed: &#123;</span><br><span class="line">    computedList: function () &#123;</span><br><span class="line">      var vm = this</span><br><span class="line">      return this.list.filter(function (item) &#123;</span><br><span class="line">        return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  methods: &#123;</span><br><span class="line">    beforeEnter: function (el) &#123;</span><br><span class="line">      el.style.opacity = 0</span><br><span class="line">      el.style.height = 0</span><br><span class="line">    &#125;,</span><br><span class="line">    enter: function (el, done) &#123;</span><br><span class="line">      var delay = el.dataset.index * 150</span><br><span class="line">      setTimeout(function () &#123;</span><br><span class="line">        Velocity(</span><br><span class="line">          el,</span><br><span class="line">          &#123; opacity: 1, height: &#x27;1.6em&#x27; &#125;,</span><br><span class="line">          &#123; complete: done &#125;</span><br><span class="line">        )</span><br><span class="line">      &#125;, delay)</span><br><span class="line">    &#125;,</span><br><span class="line">    leave: function (el, done) &#123;</span><br><span class="line">      var delay = el.dataset.index * 150</span><br><span class="line">      setTimeout(function () &#123;</span><br><span class="line">        Velocity(</span><br><span class="line">          el,</span><br><span class="line">          &#123; opacity: 0, height: 0 &#125;,</span><br><span class="line">          &#123; complete: done &#125;</span><br><span class="line">        )</span><br><span class="line">      &#125;, delay)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<h3 id="可复用的过渡"><a href="#可复用的过渡" class="headerlink" title="可复用的过渡"></a>可复用的过渡</h3><p>​        可以使用Vue组件系统的实现复用。只需要将 transition 或者 transition-group 作为根组件。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;my-special-transition&#x27;, &#123;</span><br><span class="line">  template: &#x27;\</span><br><span class="line">    &lt;transition\</span><br><span class="line">      name=&quot;very-special-transition&quot;\</span><br><span class="line">      mode=&quot;out-in&quot;\</span><br><span class="line">      v-on:before-enter=&quot;beforeEnter&quot;\</span><br><span class="line">      v-on:after-enter=&quot;afterEnter&quot;\</span><br><span class="line">    &gt;\</span><br><span class="line">      &lt;slot&gt;&lt;/slot&gt;\</span><br><span class="line">    &lt;/transition&gt;\</span><br><span class="line">  &#x27;,</span><br><span class="line">  methods: &#123;</span><br><span class="line">    beforeEnter: function (el) &#123;</span><br><span class="line">      // ...</span><br><span class="line">    &#125;,</span><br><span class="line">    afterEnter: function (el) &#123;</span><br><span class="line">      // ...</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​    当然，可以使用函数式组件来完成这个任务。函数式组件我们后面在进行了解。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;my-special-transition&#x27;, &#123;</span><br><span class="line">  functional: true,</span><br><span class="line">  render: function (createElement, context) &#123;</span><br><span class="line">    var data = &#123;</span><br><span class="line">      props: &#123;</span><br><span class="line">        name: &#x27;very-special-transition&#x27;,</span><br><span class="line">        mode: &#x27;out-in&#x27;</span><br><span class="line">      &#125;,</span><br><span class="line">      on: &#123;</span><br><span class="line">        beforeEnter: function (el) &#123;</span><br><span class="line">          // ...</span><br><span class="line">        &#125;,</span><br><span class="line">        afterEnter: function (el) &#123;</span><br><span class="line">          // ...</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    return createElement(&#x27;transition&#x27;, data, context.children)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<h3 id="动态过渡"><a href="#动态过渡" class="headerlink" title="动态过渡"></a>动态过渡</h3><p>​        在Vue中，过渡也是数据驱动的。所以name也可以使用 v-bind 来进行绑定。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;transition v-bind:name=&quot;transitionName&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        所有的过渡 attribute 都可以动态绑定。因为事件钩子都是方法。所以根据组件的状态不同，过渡也会有不同的表现。</p>
<h2 id="状态过渡"><a href="#状态过渡" class="headerlink" title="状态过渡"></a>状态过渡</h2><p>​        数据元素本身的特效，这些数据要么本身就以数值形式存储，要么可以转换为数值。</p>
<ul>
<li>数字和运算</li>
<li>颜色的显示</li>
<li>SVG 节点的位置</li>
<li>元素的大小和其他的 property</li>
</ul>
<h3 id="状态动画与侦听器"><a href="#状态动画与侦听器" class="headerlink" title="状态动画与侦听器"></a>状态动画与侦听器</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&lt;script src=&quot;https://cdn.jsdelivr.net/npm/tween.js@16.3.4&quot;&gt;&lt;/script&gt;</span><br><span class="line">&lt;script src=&quot;https://cdn.jsdelivr.net/npm/color-js@1.0.3&quot;&gt;&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;div id=&quot;example-7&quot;&gt;</span><br><span class="line">  &lt;input</span><br><span class="line">    v-model=&quot;colorQuery&quot;</span><br><span class="line">    v-on:keyup.enter=&quot;updateColor&quot;</span><br><span class="line">    placeholder=&quot;Enter a color&quot;</span><br><span class="line">  &gt;</span><br><span class="line">  &lt;button v-on:click=&quot;updateColor&quot;&gt;Update&lt;/button&gt;</span><br><span class="line">  &lt;p&gt;Preview:&lt;/p&gt;</span><br><span class="line">  &lt;span</span><br><span class="line">    v-bind:style=&quot;&#123; backgroundColor: tweenedCSSColor &#125;&quot;</span><br><span class="line">    class=&quot;example-7-color-preview&quot;</span><br><span class="line">  &gt;&lt;/span&gt;</span><br><span class="line">  &lt;p&gt;&#123;&#123; tweenedCSSColor &#125;&#125;&lt;/p&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line">var Color = net.brehaut.Color</span><br><span class="line"></span><br><span class="line">new Vue(&#123;</span><br><span class="line">  el: &#x27;#example-7&#x27;,</span><br><span class="line">  data: &#123;</span><br><span class="line">    colorQuery: &#x27;&#x27;,</span><br><span class="line">    color: &#123;</span><br><span class="line">      red: 0,</span><br><span class="line">      green: 0,</span><br><span class="line">      blue: 0,</span><br><span class="line">      alpha: 1</span><br><span class="line">    &#125;,</span><br><span class="line">    tweenedColor: &#123;&#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  created: function () &#123;</span><br><span class="line">    this.tweenedColor = Object.assign(&#123;&#125;, this.color)</span><br><span class="line">  &#125;,</span><br><span class="line">  watch: &#123;</span><br><span class="line">    color: function () &#123;</span><br><span class="line">      function animate () &#123;</span><br><span class="line">        if (TWEEN.update()) &#123;</span><br><span class="line">          requestAnimationFrame(animate)</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      new TWEEN.Tween(this.tweenedColor)</span><br><span class="line">        .to(this.color, 750)</span><br><span class="line">        .start()</span><br><span class="line"></span><br><span class="line">      animate()</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  computed: &#123;</span><br><span class="line">    tweenedCSSColor: function () &#123;</span><br><span class="line">      return new Color(&#123;</span><br><span class="line">        red: this.tweenedColor.red,</span><br><span class="line">        green: this.tweenedColor.green,</span><br><span class="line">        blue: this.tweenedColor.blue,</span><br><span class="line">        alpha: this.tweenedColor.alpha</span><br><span class="line">      &#125;).toCSS()</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  methods: &#123;</span><br><span class="line">    updateColor: function () &#123;</span><br><span class="line">      this.color = new Color(this.colorQuery).toRGB()</span><br><span class="line">      this.colorQuery = &#x27;&#x27;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.example-7-color-preview &#123;</span><br><span class="line">  display: inline-block;</span><br><span class="line">  width: 50px;</span><br><span class="line">  height: 50px;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="动态状态过渡"><a href="#动态状态过渡" class="headerlink" title="动态状态过渡"></a>动态状态过渡</h3><p>​        就像 Vue 的过渡组件一样，数据背后状态过渡会实时更新，这对于原型设计十分有用。当你修改一些变量，即使是一个简单的 SVG 多边形也可实现很多难以想象的效果。</p>
<h3 id="把过渡放到组件里"><a href="#把过渡放到组件里" class="headerlink" title="把过渡放到组件里"></a>把过渡放到组件里</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line">&lt;script src=&quot;https://cdn.jsdelivr.net/npm/tween.js@16.3.4&quot;&gt;&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;div id=&quot;example-8&quot;&gt;</span><br><span class="line">  &lt;input v-model.number=&quot;firstNumber&quot; type=&quot;number&quot; step=&quot;20&quot;&gt; +</span><br><span class="line">  &lt;input v-model.number=&quot;secondNumber&quot; type=&quot;number&quot; step=&quot;20&quot;&gt; =</span><br><span class="line">  &#123;&#123; result &#125;&#125;</span><br><span class="line">  &lt;p&gt;</span><br><span class="line">    &lt;animated-integer v-bind:value=&quot;firstNumber&quot;&gt;&lt;/animated-integer&gt; +</span><br><span class="line">    &lt;animated-integer v-bind:value=&quot;secondNumber&quot;&gt;&lt;/animated-integer&gt; =</span><br><span class="line">    &lt;animated-integer v-bind:value=&quot;result&quot;&gt;&lt;/animated-integer&gt;</span><br><span class="line">  &lt;/p&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line">// 这种复杂的补间动画逻辑可以被复用</span><br><span class="line">// 任何整数都可以执行动画</span><br><span class="line">// 组件化使我们的界面十分清晰</span><br><span class="line">// 可以支持更多更复杂的动态过渡</span><br><span class="line">// 策略。</span><br><span class="line">Vue.component(&#x27;animated-integer&#x27;, &#123;</span><br><span class="line">  template: &#x27;&lt;span&gt;&#123;&#123; tweeningValue &#125;&#125;&lt;/span&gt;&#x27;,</span><br><span class="line">  props: &#123;</span><br><span class="line">    value: &#123;</span><br><span class="line">      type: Number,</span><br><span class="line">      required: true</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  data: function () &#123;</span><br><span class="line">    return &#123;</span><br><span class="line">      tweeningValue: 0</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  watch: &#123;</span><br><span class="line">    value: function (newValue, oldValue) &#123;</span><br><span class="line">      this.tween(oldValue, newValue)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  mounted: function () &#123;</span><br><span class="line">    this.tween(0, this.value)</span><br><span class="line">  &#125;,</span><br><span class="line">  methods: &#123;</span><br><span class="line">    tween: function (startValue, endValue) &#123;</span><br><span class="line">      var vm = this</span><br><span class="line">      function animate () &#123;</span><br><span class="line">        if (TWEEN.update()) &#123;</span><br><span class="line">          requestAnimationFrame(animate)</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      new TWEEN.Tween(&#123; tweeningValue: startValue &#125;)</span><br><span class="line">        .to(&#123; tweeningValue: endValue &#125;, 500)</span><br><span class="line">        .onUpdate(function () &#123;</span><br><span class="line">          vm.tweeningValue = this.tweeningValue.toFixed(0)</span><br><span class="line">        &#125;)</span><br><span class="line">        .start()</span><br><span class="line"></span><br><span class="line">      animate()</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">// 所有的复杂度都已经从 Vue 的主实例中移除！</span><br><span class="line">new Vue(&#123;</span><br><span class="line">  el: &#x27;#example-8&#x27;,</span><br><span class="line">  data: &#123;</span><br><span class="line">    firstNumber: 20,</span><br><span class="line">    secondNumber: 40</span><br><span class="line">  &#125;,</span><br><span class="line">  computed: &#123;</span><br><span class="line">    result: function () &#123;</span><br><span class="line">      return this.firstNumber + this.secondNumber</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<h3 id="赋予设计以生命"><a href="#赋予设计以生命" class="headerlink" title="赋予设计以生命"></a>赋予设计以生命</h3>
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/29/Vue/Vue2%E6%95%99%E7%A8%8B/Vue2-%E6%95%99%E7%A8%8B-%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3%E7%BB%84%E4%BB%B6/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/29/Vue/Vue2%E6%95%99%E7%A8%8B/Vue2-%E6%95%99%E7%A8%8B-%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3%E7%BB%84%E4%BB%B6/" class="post-title-link" itemprop="url">Vue-使用-深入了解组件</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-29 23:15:14" itemprop="dateCreated datePublished" datetime="2021-10-29T23:15:14+08:00">2021-10-29</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/" itemprop="url" rel="index"><span itemprop="name">Vue</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/Vue2%E6%96%87%E6%A1%A3/" itemprop="url" rel="index"><span itemprop="name">Vue2文档</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="组件注册"><a href="#组件注册" class="headerlink" title="组件注册"></a>组件注册</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cn.vuejs.org/v2/guide/components-registration.html</span><br></pre></td></tr></table></figure>



<h2 id="组件名"><a href="#组件名" class="headerlink" title="组件名"></a>组件名</h2><h3 id="组件名大小写"><a href="#组件名大小写" class="headerlink" title="组件名大小写"></a>组件名大小写</h3><p>​        对于大小写的组件名，在使用的时候大写会变成 -+小写的形式。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">myComPonent</span><br><span class="line"></span><br><span class="line">my-com-ponent</span><br></pre></td></tr></table></figure>



<h2 id="全局注册"><a href="#全局注册" class="headerlink" title="全局注册"></a>全局注册</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;component-a&#x27;, &#123; /* ... */ &#125;)</span><br></pre></td></tr></table></figure>

<p>​        这样创建就是全局注册的，只要注册了之后，后面的Vue实例都可以直接使用。</p>
<h2 id="局部注册"><a href="#局部注册" class="headerlink" title="局部注册"></a>局部注册</h2><p>​        全局注册会不可避免的增加性能的消耗，浪费了很多时间。所以可以使用局部注册的方式进行注册，将组件注册在实例的内部，因此在实例被销毁时也会被销毁。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">const ComponentA = &#123; /* ... */ &#125;;</span><br><span class="line"></span><br><span class="line">new Vue(&#123;</span><br><span class="line">  el: &#x27;#app&#x27;,</span><br><span class="line">  components: &#123;</span><br><span class="line">    &#x27;component-a&#x27;: ComponentA,</span><br><span class="line">    &#x27;component-b&#x27;: ComponentB</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        简单来说就是 ComponentsA 里面的对象就是 new一个Vue实例的对象。然后再在components里面进行new的创建，所以将作用域限制到了一定的范围。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">const C = &#123;</span><br><span class="line">  template: `&lt;div&gt;22&lt;/div&gt;`,</span><br><span class="line">&#125;</span><br><span class="line">const ComponentA = &#123;</span><br><span class="line">  el: &#x27;#ap&#x27;,</span><br><span class="line">  //这里是局部组件创建再加上了一个组件的创建，否则一个父组件，两个局部组件内部是不能相互调用的。</span><br><span class="line">  components: &#123;</span><br><span class="line">    &#x27;com&#x27;: C,</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">const app = new Vue(&#123;</span><br><span class="line">  el: &#x27;#app&#x27;,</span><br><span class="line">  data: &#123;</span><br><span class="line">    a: 1</span><br><span class="line">  &#125;,</span><br><span class="line">  components: &#123;</span><br><span class="line">    &#x27;comA&#x27;: ComponentA,</span><br><span class="line">    &#x27;com&#x27;: C,</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<h2 id="模块系统"><a href="#模块系统" class="headerlink" title="模块系统"></a>模块系统</h2><p>​        简单来说就是可以使用 import / require 来使用一个模块系统。</p>
<h3 id="在模块系统中局部注册"><a href="#在模块系统中局部注册" class="headerlink" title="在模块系统中局部注册"></a>在模块系统中局部注册</h3><p>​        简单来说，下面这个是取出了一个对象。这个是一个ES6的模块化导出的默认导出的写法。</p>
<p>​        所以简单来说就是将对象进行导出。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">import ComponentA from &#x27;./Component&#x27;;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">export default &#123;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        我们先理清一下思路</p>
<ul>
<li>首先，Vue的components里面使用的是一个对象，这个对象是那个实例对象。其次对于这个命名的思路是因为是es6的对象赋值的方式</li>
<li>然后就是导入 import 和 export default 这里导入和导出对象。</li>
<li>所以其实还是有思路的。</li>
</ul>
<h3 id="基础组件的自动化全局注册"><a href="#基础组件的自动化全局注册" class="headerlink" title="基础组件的自动化全局注册"></a>基础组件的自动化全局注册</h3><p>​        require.context 可以全局注册组件。但是需要使用webpack或者使用了VueCLI3+（因为内部使用了webpack）</p>
<p>​        <strong>什么是 require.context ：</strong></p>
<ul>
<li>首先，是一个webpack的api。</li>
<li>其次，这个api用于实现自动化导入模块。就是对于一个文件引入很多模块的情况，可以使用这个api，会遍历指定的文件，然后进行自动导入，不需要每次显式的调用import导入模块。</li>
<li>进行一个更细粒度的模块引入。</li>
</ul>
<p>​        <strong>一个使用时机</strong>：</p>
<ul>
<li>首先就是需要引入很多模块</li>
<li>其次就是这个模块的处于同一父文件位置，所以对于基础组件来说是非常合适的。</li>
</ul>
<p>​        require.context 的参数：</p>
<ul>
<li><p>directory，String类型</p>
<ul>
<li>文件目录位置，</li>
</ul>
</li>
<li><p>includeSubdirs，Boolean类型</p>
<ul>
<li>表示是否包含文件的子目录，可选参数，默认是 true</li>
</ul>
</li>
<li><p>filter，RegExp正则表达式类型</p>
<ul>
<li>表示过滤某些文件。可选参数，默认是 <code>/^\.\/.*$/</code> 指的是所有文件。（这里是webpack写的，但是我没有理解这个正则）。</li>
</ul>
</li>
<li><p>mode，String类型</p>
<ul>
<li><p>表示加载的方式， sync，eager，weak，lazy，lazy-once。默认值是sync。</p>
</li>
<li><p>```<br>sync<br>eager</p>
<pre><code>不会生成额外的chunk，所有模块当成当前chunk引入。没有额外的网络请求，但是会返回一个resolved的Promise。
</code></pre>
<p>weak</p>
<pre><code>这个没有看懂，大概可能是尝试加载，不可用返回一个reject的Promise。
</code></pre>
<p>lazy</p>
<pre><code>为每一个导入的模块生成一个可延迟加载的chunk。简单来说就是将以异步方式加载。
</code></pre>
<p>lazy-once</p>
<pre><code>生成一个可以满足所有的可延迟加载的chunk。这个chunk将第一次调用时获取，随后使用相同的网络响应。
</code></pre>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">大概看懂了之后，我们再看一下组件的自动化全局注册</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>import Vue from ‘vue’<br>import upperFirst from ‘lodash/upperFirst’<br>import camelCase from ‘lodash/camelCase’</p>
</li>
</ul>
</li>
</ul>
<p>const requireComponent = require.context(<br>  // 其组件目录的相对路径<br>  ‘./components’,<br>  // 是否查询其子目录<br>  false,<br>  // 匹配基础组件文件名的正则表达式<br>  /Base[A-Z]\w+.(vue|js)$/<br>)</p>
<p>requireComponent.keys().forEach(fileName =&gt; {<br>  // 获取组件配置<br>  const componentConfig = requireComponent(fileName)</p>
<p>  // 获取组件的 PascalCase 命名<br>  const componentName = upperFirst(<br>    camelCase(<br>      // 获取和目录深度无关的文件名<br>      fileName<br>        .split(‘/‘)<br>        .pop()<br>        .replace(/.\w+$/, ‘’)<br>    )<br>  )</p>
<p>  // 全局注册组件<br>  Vue.component(<br>    componentName,<br>    // 如果这个组件选项是通过 <code>export default</code> 导出的，<br>    // 那么就会优先使用 <code>.default</code>，<br>    // 否则回退到使用模块的根。<br>    componentConfig.default || componentConfig<br>  )<br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		**其中这一部分的作用是将每个文件的模块给取了出来**</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>const requireComponent = require.context(<br>  // 其组件目录的相对路径<br>  ‘./components’,<br>  // 是否查询其子目录<br>  false,<br>  // 匹配基础组件文件名的正则表达式<br>  /Base[A-Z]\w+.(vue|js)$/<br>)</p>
<p>目录是 ./components<br>不查询子目录<br>匹配文件的形式，Basexxxx.(vue|js)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* requireComponent 通过typeof 判断是一个，function，里面存在了方法，可以使用keys方法进行获取</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">​		**这里是将requireComponent存储的组件给进行了注册。**</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>requireComponent.keys().forEach(fileName =&gt; {<br>  // 获取组件配置<br>  const componentConfig = requireComponent(fileName)</p>
<p>  // 获取组件的 PascalCase 命名<br>  const componentName = upperFirst(<br>    camelCase(<br>      // 获取和目录深度无关的文件名<br>      fileName<br>        .split(‘/‘)<br>        .pop()<br>        .replace(/.\w+$/, ‘’)<br>    )<br>  )</p>
<p>  // 全局注册组件<br>  Vue.component(<br>    componentName,<br>    // 如果这个组件选项是通过 <code>export default</code> 导出的，<br>    // 那么就会优先使用 <code>.default</code>，<br>    // 否则回退到使用模块的根。<br>    componentConfig.default || componentConfig<br>  )<br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* keys方法获取到的是文件的相对路径。使用foreach进行循环操作。foreach内部也是和forin一个意思。forin和forof的区别在于迭代器问题。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    ./App.vue</span><br><span class="line">    ./components/App.vue</span><br></pre></td></tr></table></figure>

<ul>
<li><p>然后使用 requireComponent 方法，参数为文件位置，便会获取到内容。</p>
<ul>
<li>使用 requireComponent(filename)，进行获取，就可以获取到内容。</li>
</ul>
</li>
<li><p>当然这里的一个特点是，这个requireComponent 既是一个方法，也是一个对象，因为它既能像方法一样传递参数进行操作，也可以调用keys这个方法。</p>
</li>
<li><p>这里使用的 upperFirst 和 camelCase 是 lodash里面的方法，其中 upperFirst的作用是首字母大写，而camelCase是将字符串转为驼峰命名法，比如空格，-，_将会被划分。</p>
</li>
<li><p>在这里，首先fileName是一个文件的路径和名字，所以使用split进行划分/， 然后取出最后一个，然后将后面的文件后缀改为空，然后给camelCase变为驼峰，然后返回的字符串给了upperFirst变为了首字母大写的驼峰。赋值给了componentName。</p>
<ul>
<li>```<br>const componentName = upperFirst(<br>  camelCase(<pre><code>// 获取和目录深度无关的文件名
fileName
  .split(&#39;/&#39;)
  .pop()
  .replace(/\.\w+$/, &#39;&#39;)
</code></pre>
  )<br>)<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 然后就是注册组件了，使用了 Vue.component 方法。进行注册，Vue.component 第一个参数是名字，第二个参数是需要被Vue实例的对象。</span><br><span class="line"></span><br><span class="line">  * 这里的唯一的问题就是，对于如果没有使用 export default 导出的方法，貌似不会存在 default 这个对象。但是具体的我们需要在后面才会知道。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    Vue.component(</span><br><span class="line">      componentName,</span><br><span class="line">      // 如果这个组件选项是通过 `export default` 导出的，</span><br><span class="line">      // 那么就会优先使用 `.default`，</span><br><span class="line">      // 否则回退到使用模块的根。</span><br><span class="line">      componentConfig.default || componentConfig</span><br><span class="line">    )</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<p>​        <strong>如何实现一个方法带有对象的使用。</strong></p>
<p>​        这里我的一个想法就是修改原型链了，因为JavaScript任何都是存在原型链的，对于方法来说，也是有一个原型链的。简单来理解，方法既可以使用，又可以当作一个构造器来创建对象。</p>
<ul>
<li>作为一个构造器来说，方法需要记住的是prototype的指向</li>
<li>而对于方法的执行来说，需要记住的是 __proto__ 的指向。所以这里对 __proto__ 里面创建了一个方法，然后通过调用这个方法来获取了keys，并且这个本身也是一个方法。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">function T() &#123;</span><br><span class="line">  return 1;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">T.__proto__.keys = function () &#123;</span><br><span class="line">  console.log(2);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h1 id="Prop"><a href="#Prop" class="headerlink" title="Prop"></a>Prop</h1><h2 id="Prop的大小写"><a href="#Prop的大小写" class="headerlink" title="Prop的大小写"></a>Prop的大小写</h2><p>​        简单来说就是驼峰命名法(camelCase)会在HTML上进行使用时需要转换为短横线分割命名(kebab-case)。因为HTML文档解析是大小写不敏感的，所以 postTitle 会被解析成 posttitle</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;blog-post :post-title=&quot;a&quot;&gt;&lt;/blog-post&gt;</span><br><span class="line"></span><br><span class="line">Vue.component(&#x27;blog-post&#x27;, &#123;</span><br><span class="line">  // 在 JavaScript 中是 camelCase 的</span><br><span class="line">  props: [&#x27;postTitle&#x27;],</span><br><span class="line">  template: &#x27;&lt;h3&gt;&#123;&#123; postTitle &#125;&#125;&lt;/h3&gt;&#x27;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>​        但是如果是使用的字符串模板，那么就不会有这个限制。</p>
<p>​        意思就是说，使用template这种，模板是字符串的，应该是中间有个步骤在解析的时候会将驼峰自动转换为短横线。所以没有问题。</p>
<h2 id="Prop类型"><a href="#Prop类型" class="headerlink" title="Prop类型"></a>Prop类型</h2><ul>
<li><p>正常prop在使用的时候是使用的数组，加上字符串进行存储。此时的prop是一个数组的形式。</p>
<ul>
<li><p>```<br>props: [‘title’, ‘author’]</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 当然我们可以设置prop的值的类型。此时的prop是一个对象的形式。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    props: &#123;</span><br><span class="line">      title: String,</span><br><span class="line">      likes: Number,</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></li>
<li><p>对于设置了类型，但是类型对不上的，会报错，但是还是会正常显示，并不会进行类型转换。</p>
</li>
</ul>
</li>
<li><p>后面还会将一个写法，props里面的prop也是一个对象，我们后续再进行一个讲解。</p>
<ul>
<li>```<br>props: {<pre><code>propA: &#123;
    type: String,
    default: &#39;111&#39;,
    required: true
&#125;
</code></pre>
}<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 传递静态或动态Prop</span><br><span class="line"></span><br><span class="line">​		简单来说，prop的传递是通过在使用组件时，添加上了attribute属性在DOM树上，然后再进行的传递，所以这个是可以使用 v-bind 进行绑定的。</span><br><span class="line"></span><br><span class="line">​		当然通过这里我也学会一个小case，就是在这样使用的时候，会把42作为一个数字传递过去，而不是字符串，对于布尔值也是一样，如果要传递一个字符串，需要再使用 &#x27;&#x27; 进行划分。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<blog-post :likes="42"></blog-post><br>42， false， [12, 41]， {}<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		对于要传入一个对象的所有property，我们可以使用 v-bind，进行直接传入。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<blog-post v-bind="post"></blog-post></li>
</ul>
</li>
</ul>
<p>就等于将 post 里面的对象进行传递</p>
<p>&lt;blog-post<br>  v-bind:id=”post.id”<br>  v-bind:title=”post.title”</p>
<blockquote>

</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		当然这里的优先级来说，首先对于子组件没有的prop，是不会进行赋值的，其次对于对象里面存在，同时在外面也进行过一个操作的。比如下面这个情况，是以单独的为重点。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><blog-post :post-title="a" v-bind="post"></blog-post></p>
<p>post: {<br>  id: 1,<br>  ‘post-title’: ‘xxxx’,<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		其次，就是对于对象里面的属性，在子组件的props里没有，但是确实这个标签的属性的，会被挂载为一个属性。</span><br><span class="line"></span><br><span class="line">​		比如：下面这个title就是子组件不存在的，但是属于标签上的属性，我们就可以看到DOM解构上就存在了，同时，我们也发现，id属性应该也是DOM树上的，但是却没有，应该是对于props里面存在的属性会被拦截，只有不在的才会跳出拦截。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>post: {<br>  id: 1,<br>  title: ‘xxxx’,<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 单向数据流</span><br><span class="line"></span><br><span class="line">​		简单来说，对于这个父子组件的值的传递，所以为了保证子组件意外变更父级组件的状态，我们让子组件不能进行更新，更新会报出警告。并且不能进行更改。</span><br><span class="line"></span><br><span class="line">​		然而记住，这个只是对栈进行了一个锁定，并没有对堆进行锁定，所以简单来说就是值类型是会被警告，但是对于引用类型来说，还是可以直接进行修改，并不会爆出警告。</span><br><span class="line"></span><br><span class="line">​		这是一个需要记住的问题。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">​		对于会进行修改数据，但是又不想污染了父组件的data的，我们这里，有两个方式</span><br><span class="line"></span><br><span class="line">* 第一种就是使用了data将props的值重新进行赋值了 **这个子组件接下来希望将其作为一个本地的 prop 数据来使用** 。</span><br><span class="line">  * ```</span><br><span class="line">    props: [&#x27;initialCounter&#x27;],</span><br><span class="line">    data: function () &#123;</span><br><span class="line">      return &#123;</span><br><span class="line">        counter: this.initialCounter</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>第二种就是使用计算属性，简单来说就是并没有修改原数据，仅仅只是使用了原数据。常用于 <strong>以一种原始的值传入且需要进行转换</strong> 。</li>
</ul>
<h2 id="Prop-验证"><a href="#Prop-验证" class="headerlink" title="Prop 验证"></a>Prop 验证</h2><p>​        验证类型是否满足需求，以及是否是必填项。</p>
<h3 id="类型检查"><a href="#类型检查" class="headerlink" title="类型检查"></a>类型检查</h3><ul>
<li>类型的限制</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">props: &#123;</span><br><span class="line">	A: Number,</span><br><span class="line">	B: [Number, String],</span><br><span class="line">	C: &#123;</span><br><span class="line">		type: String,</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>是否为必填项和默认值</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">props: &#123;</span><br><span class="line">	A: &#123;</span><br><span class="line">		required: true,</span><br><span class="line">		default: &#x27;AA&#x27;,</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<p>对象和数组的默认值必须从一个工厂函数获取。简单来说就是需要是一个函数，函数返回一个对象或者数组。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">default: () =&gt; &#123;</span><br><span class="line">	return &#123;</span><br><span class="line">		a: 1</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<ul>
<li>自定义一个验证函数</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">A: &#123;</span><br><span class="line">	validator: function(value) &#123;</span><br><span class="line">		//返回值是 true 和 false</span><br><span class="line">		return true;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<blockquote>
<p>​        注意那些 prop 会在一个组件实例创建<strong>之前</strong>进行验证，所以实例的 property (如 <code>data</code>、<code>computed</code> 等) 在 <code>default</code> 或 <code>validator</code> 函数中是不可用的。</p>
</blockquote>
<h2 id="非-Prop-的-Attribute"><a href="#非-Prop-的-Attribute" class="headerlink" title="非 Prop 的 Attribute"></a>非 Prop 的 Attribute</h2><p>​        一个非 prop 的 attribute 是指传向一个组件，但是该组件并没有相应 prop 定义的 attribute。</p>
<p>​        这个在前面也有说过，因为prop的传递是在标签上进行的传递，那么怎么区别这个属性是prop的值还是我是要给标签上的值呢。这里就是非Prop的属性</p>
<p>​        简单来理解，就是对于声明的属性，但是却没有prop属性进行接收，那么就会被添加到组件的根元素上。</p>
<h3 id="替换-合并已有的-Attribute"><a href="#替换-合并已有的-Attribute" class="headerlink" title="替换/合并已有的 Attribute"></a>替换/合并已有的 Attribute</h3><p>​        简单来说就是我在组件的根元素上已经存在了这个属性，但是我在外面使用的使用对这个属性进行了重新的赋值，但是我的需求不是进行覆盖，而是进行合并，此时就是这个 替换/合并 属性</p>
<p>​        但是这里从官网上看出，并没有什么方法，但是对于 class 和 style 这两个属性，我们会进行合并操作，但是对于其他属性，比如 type 等，我们就会出现替换掉的操作。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">子组件，c-c</span><br><span class="line">div.A[type=&#x27;AA&#x27;]</span><br><span class="line"></span><br><span class="line">父组件的使用</span><br><span class="line">c-c.B[type=&#x27;BB&#x27;]</span><br></pre></td></tr></table></figure>



<h3 id="禁用-Attribute-继承"><a href="#禁用-Attribute-继承" class="headerlink" title="禁用 Attribute 继承"></a>禁用 Attribute 继承</h3><p>​        简单来说就是因为在使用这个组件时，一些没有被prop的属性会被加入根标签，但是有的时候是不想这样的，所以我们可以使用 inheritAttrs: false，代表了继承属性为false。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;my-component&#x27;, &#123;</span><br><span class="line">	//这个属性，为false，代表了多余的属性不会被记录在dom树上。（多余是指没有在props定义的），默认为true。</span><br><span class="line">  inheritAttrs: false,</span><br><span class="line">  // ...</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        当然对于需要被继承的属性，我们可以使用 $attrs 进行获取。这个属性包含了一个属性名和一个属性值。</p>
<p>​        通过 inheritAttrs 和 $attrs 这两个属性，就可以自己决定属性应该被赋予哪个元素。通常用于编写基础组件。</p>
<p>​        下面这个例子，首先，使用了 inheritAttrs 进行了拦截。对于props不存在的属性将不会出现在根元素上。然后再对input标签上添加了一个 v-bind=”$attrs” 因为$attrs 属性是一个键值对。然后将其赋值给了input标签上。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;base-input&#x27;, &#123;</span><br><span class="line">  inheritAttrs: false,</span><br><span class="line">  props: [&#x27;label&#x27;, &#x27;value&#x27;],</span><br><span class="line">  template: `</span><br><span class="line">    &lt;label&gt;</span><br><span class="line">      &#123;&#123; label &#125;&#125;</span><br><span class="line">      &lt;input</span><br><span class="line">        v-bind=&quot;$attrs&quot;</span><br><span class="line">        v-bind:value=&quot;value&quot;</span><br><span class="line">        v-on:input=&quot;$emit(&#x27;input&#x27;, $event.target.value)&quot;</span><br><span class="line">      &gt;</span><br><span class="line">    &lt;/label&gt;</span><br><span class="line">  `</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">&lt;base-input</span><br><span class="line">  label=&quot;Username:&quot;</span><br><span class="line">  v-model=&quot;username&quot;</span><br><span class="line">  required</span><br><span class="line">  placeholder=&quot;Enter your username&quot;</span><br><span class="line">&gt;&lt;/base-input&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$attrs 的值。</span><br><span class="line">&#123;</span><br><span class="line">	required: &quot;&quot;</span><br><span class="line">	placeholder: &quot;Enter your username&quot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>注意 <code>inheritAttrs: false</code> 选项<strong>不会</strong>影响 <code>style</code> 和 <code>class</code> 的绑定。</p>
</blockquote>
<p>​        通过这个方式来进行操作的话，不用担心哪个是真正的根元素。</p>
<h1 id="自定义事件"><a href="#自定义事件" class="headerlink" title="自定义事件"></a>自定义事件</h1><h2 id="事件名"><a href="#事件名" class="headerlink" title="事件名"></a>事件名</h2><p>​        首先要注意一个地方，那就是，对于 vue 的 v-on 监听来说，（语法糖是@）。这个是不会将短横线转为驼峰的。</p>
<p>​        我们从前面可以知道，对于 props 来说，传递的属性如果是短横线，那么在props里面可以使用驼峰来进行处理，但是对于事件来说不行。</p>
<p>​        这里就会好奇为什么prop可以短横线转驼峰，但是事件不能呢。有的说是JavaScript的命名规范里面不能使用短横线命名。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">this.$emit(&#x27;myEvent&#x27;)</span><br><span class="line">&lt;!-- 没有效果 --&gt;</span><br><span class="line">因为 短横线不能转换为驼峰。所以没有效果。</span><br><span class="line">&lt;my-component v-on:my-event=&quot;doSomething&quot;&gt;&lt;/my-component&gt;</span><br></pre></td></tr></table></figure>

<p>​        所以对于 @myEvent 将会被转化为 @myevent。</p>
<p>​        所以最好的建议就是全部都是用 kebab-case。这里不但有HTML大小写不敏感的原因，还有对于模板字符串来说。大小写是规定的。</p>
<h2 id="自定义组件的v-model-2-2-0"><a href="#自定义组件的v-model-2-2-0" class="headerlink" title="自定义组件的v-model 2.2.0+"></a>自定义组件的v-model 2.2.0+</h2><p>​        v-model 这个默认是利用名为 value 的prop 和 input 的事件。当然对于input的单选框和其他的会将value属性用于不同的prop。但是我们可以使用 model 选项来解决 v-model的冲突。</p>
<p>​        简单的理解一下下面的内容，prop：checked，这个默认是value，代表了使用props的checked作为v-model的绑定。event：change，默认是input，代表监听的事件名称是change，这些都是可以进行修改的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;base-checkbox&#x27;, &#123;</span><br><span class="line">  model: &#123;</span><br><span class="line">    prop: &#x27;checked&#x27;,</span><br><span class="line">    event: &#x27;change&#x27;</span><br><span class="line">  &#125;,</span><br><span class="line">  props: &#123;</span><br><span class="line">    checked: Boolean</span><br><span class="line">  &#125;,</span><br><span class="line">  template: `</span><br><span class="line">    &lt;input</span><br><span class="line">      type=&quot;checkbox&quot;</span><br><span class="line">      v-bind:checked=&quot;checked&quot;</span><br><span class="line">      v-on:change=&quot;$emit(&#x27;change&#x27;, $event.target.checked)&quot;</span><br><span class="line">    &gt;</span><br><span class="line">  `</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        比如我这里进行一个修改。就是将 prop 的checked改成了XXX，于是相对应的。props的名字也要有一个XXX的存在。同理。我可以将event改成一个AAA，那么就会将emit提交的事件名称修改为AAA。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">model: &#123;</span><br><span class="line">  prop: &#x27;XXX&#x27;,</span><br><span class="line">  event: &#x27;AA&#x27;</span><br><span class="line">&#125;,</span><br><span class="line">props: &#123;</span><br><span class="line">  XXX: String</span><br><span class="line">&#125;,</span><br><span class="line">template: `</span><br><span class="line">  &lt;input</span><br><span class="line">  :value=&quot;XXX&quot;</span><br><span class="line">  @change=&quot;$emit(&#x27;AA&#x27;, $event.target.value)&quot;</span><br><span class="line">  &gt;</span><br><span class="line">`</span><br></pre></td></tr></table></figure>

<blockquote>
<p>注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。</p>
</blockquote>
<h2 id="将原生事件绑定到组件"><a href="#将原生事件绑定到组件" class="headerlink" title="将原生事件绑定到组件"></a>将原生事件绑定到组件</h2><p>​        简单来说就是我想对一个标签进行监听，比如input监听，方法在本身，但是组件的input标签是在子组件的。那么此时我们就可以发现。子组件的输入并不会调用这个方法。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;base-input @input=&quot;onInput&quot;&gt;&lt;/base-input&gt;</span><br></pre></td></tr></table></figure>

<p>​        我们可以先做一个原生的示例。通过下面这个示例我们可以发现。在输入input的时候会输出1，2 。因为这个是冒泡的原因。所以先进行的子组件的执行，再进行的父组件的执行。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;div oninput=&quot;console.log(2);&quot;&gt;</span><br><span class="line">  &lt;input oninput=&quot;console.log(1);&quot;/&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>​        那么我们做一个vue组件的示例。并且我们也可以发现。此时就不会执行 myInput 方法了。只会执行组件内部的input的方法。不会执行外部的。原因的话。我们可以知道对于没有props接收的属性一般会被加入根元素，但是我们可以发现对于 监听属性来说，并没有加入到根元素。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;app&quot;&gt;</span><br><span class="line">  &lt;base-input @input=&quot;myInput&quot;&gt;&lt;/base-input&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">Vue.component(&#x27;base-input&#x27;, &#123;</span><br><span class="line">  template: `&lt;input @input=&quot;CInput&quot;&gt;`,</span><br><span class="line">  methods: &#123;</span><br><span class="line">    CInput() &#123;</span><br><span class="line">      console.log(&#x27;c&#x27;);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        具体的原因还不清楚。但是要记住就是直接使用监听是不会被监听成功的。有可能是监听要通过JavaScript进行操作，但是组件的元素会被替换，所以监听会失效。</p>
<p>​        因此我们可以使用 .native 修饰符 那么此时就可以将监听放入根元素了。当然，这个的效果简单来说就是会将事件绑定给根元素。但是如果本来根元素不支持这个事件，那么就会静默失败，比如 div的根元素绑定一个focus，就会失败。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;base-input @input.native=&quot;myInput&quot;&gt;&lt;/base-input&gt;</span><br></pre></td></tr></table></figure>



<p>​        此时，对于根元素并不是我想要绑定的元素，这个时候，我们知道，对于props，有一个叫做。$attrs，和 inheritAttrs 进行搭配，可以使父组件传递的props在子组件能够有一个自己规定的位置出现。那么同时事件也有一个 $listeners 属性，他是一个对象，里面包含了作用在这个组件上的监听器。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;div&gt;&lt;input v-on=&quot;$listeners&quot; @input=&quot;CInput&quot;&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>​        但是注意，如果使用了 .native 那么将不会出现在 $listeners 里面。不管 .native 是否会绑定成功。</p>
<p>​        下面这个是使用computed，这里记住一个问题，那就是 下面这个写法是会将 input 的监听进行覆盖的一个操作。但是又通过了 $emit 向上通知了父组件的 input。同理 使用 this.$listeners[‘input’] 也会覆盖input。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">computed: &#123;</span><br><span class="line">  inputListeners: function () &#123;</span><br><span class="line">    var vm = this</span><br><span class="line">    // `Object.assign` 将所有的对象合并为一个新对象</span><br><span class="line">    return Object.assign(&#123;&#125;,</span><br><span class="line">      // 我们从父级添加所有的监听器</span><br><span class="line">      this.$listeners,</span><br><span class="line">      // 然后我们添加自定义监听器，</span><br><span class="line">      // 或覆写一些监听器的行为</span><br><span class="line">      &#123;</span><br><span class="line">        // 这里确保组件配合 `v-model` 的工作</span><br><span class="line">        input: function (event) &#123;</span><br><span class="line">        	vm.$emit(&#x27;input&#x27;, event.target.value)</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>



<h2 id="sync修饰符-2-3-0"><a href="#sync修饰符-2-3-0" class="headerlink" title=".sync修饰符 2.3.0+"></a>.sync修饰符 2.3.0+</h2><p>​        因为双向绑定会带来维护上的问题。因为对于data的变更不清楚来源。</p>
<p>​        所以我们推荐 update:myPropName 来代替。在一个包含 title 的假设的组件。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">this.$emit(&#x27;update:title&#x27;, newTitle)</span><br></pre></td></tr></table></figure>

<p>​        因此就引出了sync修饰符，这算是一个语法糖。</p>
<ul>
<li><p>对于父组件来说，变化就是将 :title 和 :update:title 进行了合并，简单来说就像是进行了 v-model 的操作一样。</p>
<ul>
<li>```<br>&lt;base-input<br>  v-bind:title=”a”<br>  v-on:update:title=”a”<blockquote>

</blockquote>
<base-input :title.sync="a"></base-input><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 对于子组件来说，没有什么变化， 这里的 :title.sync 就是 @update:title 加上了 :title，所以对于 $emit 也是使用原来的 update:title 进行的提交。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    this.$emit(&#x27;update:title&#x27;, Math.random());</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<p>在这里，还有一个问题就是。我们可以发现对于 emit提交时带的参数，父组件如果要将方法写在那个标签上进行表达式的执行，那么 $event 就是第一个参数。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">this.$emit(&#x27;update:title&#x27;, 1);</span><br><span class="line"></span><br><span class="line">//这里的 $event 就是 子元素在 $emit 提交时的第二个参数，从第二个参数开始的提交就是会传递给父元素的参数。这里只是第二个，如果没有参数的话，就会为undefined</span><br><span class="line">&lt;base-input @update:title=&quot;a = $event&quot;&gt;&lt;/base-input&gt;</span><br></pre></td></tr></table></figure>



<blockquote>
<p>注意带有 <code>.sync</code> 修饰符的 <code>v-bind</code> <strong>不能</strong>和表达式一起使用 (例如 <code>v-bind:title.sync=”doc.title + ‘!’”</code> 是无效的)。取而代之的是，你只能提供你想要绑定的 property 名，类似 <code>v-model</code>。</p>
</blockquote>
<p>​        当然，这里的 sync修饰符 也可以和 v-bind 进行搭配</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;text-document v-bind.sync=&quot;doc&quot;&gt;&lt;/text-document&gt;</span><br><span class="line"></span><br><span class="line">this.$emit(&#x27;update:title&#x27;, 1111);</span><br></pre></td></tr></table></figure>



<blockquote>
<p>将 <code>v-bind.sync</code> 用在一个字面量的对象上，例如 <code>v-bind.sync=”&#123; title: doc.title &#125;”</code>，是无法正常工作的，因为在解析一个像这样的复杂表达式的时候，有很多边缘情况需要考虑。</p>
</blockquote>
<h1 id="插槽"><a href="#插槽" class="headerlink" title="插槽"></a>插槽</h1><p>​        简单来说就是，因为Vue的组件化思路，所以很多都是以组件进行的开发。但是为了降低组件和组件的解耦性，就可以使用插槽，将组件之间的联系进一步的降低。</p>
<p>​        在 2.6.0中，提供了新的语法 v-slot 来代替了 slot 和 slot-scope</p>
<h2 id="插槽内容"><a href="#插槽内容" class="headerlink" title="插槽内容"></a>插槽内容</h2><p>​        </p>
<p><strong>一个简单的示例</strong></p>
<p>​        下面的示例就代表了 Your Profile 将会代替 slot这个标签进行显示。当然 插槽的内部可以包含任何模板代码，包括HTML和其他组件，这也是我们常会使用的方法。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;navigation-link url=&quot;/profile&quot;&gt;</span><br><span class="line">  Your Profile</span><br><span class="line">&lt;/navigation-link&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;a&gt;</span><br><span class="line">  &lt;slot&gt;&lt;/slot&gt;</span><br><span class="line">&lt;/a&gt;</span><br></pre></td></tr></table></figure>



<h2 id="编译作用域"><a href="#编译作用域" class="headerlink" title="编译作用域"></a>编译作用域</h2><p>​        简单来说，看下面这个代码，这个 a 应该是 父级组件上的 a呢，还是子组件上的a呢。</p>
<p>​        最终的结果就是这个是 父级组件上的a。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;div&gt;</span><br><span class="line">	&lt;base-input&gt;&#123;&#123; a &#125;&#125;&lt;/base-input&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>这里有条规则</p>
<blockquote>
<p>父级模板里的所有内容都是在父级作用域中编译的；子模板里的所有内容都是在子作用域中编译的。</p>
</blockquote>
<h2 id="后背内容"><a href="#后背内容" class="headerlink" title="后背内容"></a>后背内容</h2><p>​        简单来说就是一个插槽的默认值。简单来说就是写在 slot 里面的内容就是 插槽的默认值。</p>
<p>​        如果你在使用组件的时候没有使用插槽，那么就会使用这个默认的内容，并且这个默认的内容的作用域是在子组件的。</p>
<p>​        如果提供有内容，那么便会渲染来取代内容。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;div&gt;&lt;slot&gt;&#123;&#123; x &#125;&#125;&lt;/slot&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure>



<h2 id="具名插槽"><a href="#具名插槽" class="headerlink" title="具名插槽"></a>具名插槽</h2><p>​        简单来说就是使用name将插槽能够指定的使用在某个位置。对于没有使用name的，会有一个默认的name default。 </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;slot name=&quot;header&quot;&gt;&lt;/slot&gt;</span><br></pre></td></tr></table></figure>

<p>​        那么在使用这个具名插槽的时候，我们就可以使用一个 template 进行包裹，然后在里面使用 v-slot指令，并以 v-slot 的参数的形式提供名称。</p>
<p>​        从下面的代码可以看出，对于使用了 template加上v-slot的，就是寻找name相对应的。对于没有使用的就会被作为一个默认，就算中间隔了一个template v-slot 也一样。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;base-layout&gt;</span><br><span class="line">  &lt;template v-slot:header&gt;</span><br><span class="line">    &lt;h1&gt;Here might be a page title&lt;/h1&gt;</span><br><span class="line">  &lt;/template&gt;</span><br><span class="line"></span><br><span class="line">  &lt;p&gt;A paragraph for the main content.&lt;/p&gt;</span><br><span class="line">  &lt;p&gt;And another one.&lt;/p&gt;</span><br><span class="line"></span><br><span class="line">  &lt;template v-slot:footer&gt;</span><br><span class="line">    &lt;p&gt;Here&#x27;s some contact info&lt;/p&gt;</span><br><span class="line">  &lt;/template&gt;</span><br><span class="line">&lt;/base-layout&gt;</span><br></pre></td></tr></table></figure>

<p>​        当然，为了语义的方便，我们建议还是可以将默认的放入一个 template v-slot:default，当然，这个default不要也可以，但是如果加了default，那么就不会将其他外层标签也加入默认，但是如果没有加上default的话，那么就会加入默认。</p>
<p>​        比如：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;template v-slot:default&gt;</span><br><span class="line">  &lt;p&gt;A paragraph for the main content.&lt;/p&gt;</span><br><span class="line">  &lt;p&gt;And another one.&lt;/p&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line">//下面这个不会显示。</span><br><span class="line">&lt;p&gt;And another one.&lt;/p&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;p&gt;A paragraph for the main content.&lt;/p&gt;</span><br><span class="line">  &lt;p&gt;And another one.&lt;/p&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line">//上面的template没有使用default，下面这个会显示出来，因为都被算在了插槽里面</span><br><span class="line">&lt;p&gt;And another one.&lt;/p&gt;</span><br></pre></td></tr></table></figure>



<h2 id="作用域插槽"><a href="#作用域插槽" class="headerlink" title="作用域插槽"></a>作用域插槽</h2><p>​        2.6.0 废弃了 slot-scope</p>
<p>​        因为我们可以知道，插槽的默认的作用域是编译时的环境，所以一般常常是父级作用域，那么此时我们要如何将作用域作用域子级。</p>
<p>​        这个时候就是要使用作用域插槽的时候了。</p>
<ul>
<li>简单来说就是子组件在进行slot创建时，通过 v-bind 绑定一个属性，然后属性的值是data的值。</li>
<li>然后在使用的时候，通过 v-slot:xx=”xxx” 进行了属性的获取，这里 xxx就是子组件传递过来的一系列的属性而形成的对象。</li>
<li>此时我们就可以在父组件里面使用到子组件的data了，当然，建议这个还是少使用吧，因为这个造成了组件的透明度降低。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;slot :x=&quot;x1&quot;&gt;&lt;/slot&gt;</span><br><span class="line"></span><br><span class="line">&lt;template v-slot:default=&quot;a&quot;&gt;</span><br><span class="line">a.x</span><br><span class="line">&lt;/template&gt;</span><br></pre></td></tr></table></figure>



<h3 id="独占默认插槽的缩写语法"><a href="#独占默认插槽的缩写语法" class="headerlink" title="独占默认插槽的缩写语法"></a>独占默认插槽的缩写语法</h3><p>​        就是说，只有被提供的内容只存在默认插槽的存在时，组件的标签才可以被当作插槽的模板来使用。此时我们就可以直接把 v-slot 用在组件上。</p>
<p>​        这里我们首先知道 v-slot 可以使用在组件上，并且插槽是可以接收一个组件的。但是我们后面可以发现，如果直接使用组件，会出现插槽的位置无法正确的定位。</p>
<p>​        然后我么可以发现，其实对组件是不能进行插槽的定位的。意思就是说，对于组件来说，使用插槽的 v-slot 不能定位到对应的具名插槽。</p>
<p>​        比如下面这个情况，我开始以为 v-slot:footer 和 v-slot:header，都会按照正确的位置进行拜访，因为这个就是具名插槽的作用，只能用于template，对于下面这个test组件，虽然我们也使用了 v-slot:header 但是他并没有去header，而是就为普通的标签的行为。v-slot不会在除了template上起作用。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;base-input&gt;</span><br><span class="line">  &lt;template v-slot:footer&gt;</span><br><span class="line">  	&lt;ttt&gt;&lt;/ttt&gt;</span><br><span class="line">  &lt;/template&gt;</span><br><span class="line"></span><br><span class="line">  &lt;p&gt;123&lt;/p&gt;</span><br><span class="line">  &lt;p&gt;111&lt;/p&gt;</span><br><span class="line"></span><br><span class="line">  &lt;test v-slot:header&gt;&lt;/test&gt;</span><br><span class="line">&lt;/base-input&gt;</span><br></pre></td></tr></table></figure>



<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;current-user v-slot:default=&quot;slotProps&quot;&gt;</span><br><span class="line">  &#123;&#123; slotProps.user.firstName &#125;&#125;</span><br><span class="line">&lt;/current-user&gt;</span><br></pre></td></tr></table></figure>

<p>​        缩写语法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;current-user v-slot=&quot;slotProps&quot;&gt;</span><br><span class="line">  &#123;&#123; slotProps.user.firstName &#125;&#125;</span><br><span class="line">&lt;/current-user&gt;</span><br></pre></td></tr></table></figure>

<p>​        案例形式。简单来说就是，如果base-input内部只有一个默认插槽，那么我们可以将这个 base-input 内部的整体都作为一个 slot的代替，如果是以前， base-input&gt;template[v-slot=”slotProps”] 但是我们可以将template进行省略，所以变成了 base-input[v-slot=”slotProps”]</p>
<p>​        当然，上面这个也是进行了缩写了的。完整的话，需要加上 v-slot:default。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;base-input v-slot=&quot;slotProps&quot;&gt;</span><br><span class="line">&lt;/base-input&gt;</span><br></pre></td></tr></table></figure>



<h3 id="解构插槽Prop"><a href="#解构插槽Prop" class="headerlink" title="解构插槽Prop"></a>解构插槽Prop</h3><p>​        简单来说就是说，作用域插槽的内部原理就是将插槽的内容包裹在一个参数的函数内部。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">function (slotProps) &#123;</span><br><span class="line">  // 插槽内容</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        在下面这个标签的使用里。使用了解构赋值的形式， { user } = slotProps，在这里，解构赋值的效果就是，取出了 slotProps的user给了 user。当然我们也可以使用其他的解构赋值的行为。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;current-user v-slot=&quot;&#123; user &#125;&quot;&gt;</span><br><span class="line">  &#123;&#123; user.firstName &#125;&#125;</span><br><span class="line">&lt;/current-user&gt;</span><br></pre></td></tr></table></figure>



<h2 id="动态插槽名"><a href="#动态插槽名" class="headerlink" title="动态插槽名"></a>动态插槽名</h2><p>​        2.6.0 新增</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;template v-slot:[dynamicSlotName]&gt;</span><br><span class="line">  ...</span><br><span class="line">&lt;/template	&gt;</span><br></pre></td></tr></table></figure>



<h2 id="具名插槽的缩写"><a href="#具名插槽的缩写" class="headerlink" title="具名插槽的缩写"></a>具名插槽的缩写</h2><p>​        2.6.0 新增</p>
<p>​        简单来说，就是插槽的语法糖，v-slot =&gt; #，但是对于没有参数的话是无效的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;current #header=&quot;&#123; user &#125;&quot;&gt;&lt;/current&gt;</span><br><span class="line">//下面这个是无效的。</span><br><span class="line">&lt;current #=&quot;&#123; user &#125;&quot;&gt;&lt;/current&gt;</span><br></pre></td></tr></table></figure>



<h1 id="动态组件-amp-异步组件"><a href="#动态组件-amp-异步组件" class="headerlink" title="动态组件&amp;异步组件"></a>动态组件&amp;异步组件</h1><h2 id="在动态组件上使用-keep-alive"><a href="#在动态组件上使用-keep-alive" class="headerlink" title="在动态组件上使用 keep-alive"></a>在动态组件上使用 keep-alive</h2><p>​        之前，我们使用 is 属性来对组件进行切换。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;component v-bind:is=&quot;currentTabComponent&quot;&gt;&lt;/component&gt;</span><br></pre></td></tr></table></figure>

<p>​        现在，我们在组件进行切换的时候，想要保存组件的状态。以避免重复的渲染。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 失活的组件将会被缓存！--&gt;</span><br><span class="line">&lt;keep-alive&gt;</span><br><span class="line">  &lt;component v-bind:is=&quot;currentTabComponent&quot;&gt;&lt;/component&gt;</span><br><span class="line">&lt;/keep-alive&gt;</span><br></pre></td></tr></table></figure>



<h2 id="异步组件"><a href="#异步组件" class="headerlink" title="异步组件"></a>异步组件</h2><p>​        将应用分割成小一些的代码块，并且只在需要的时候才从服务器进行加载。对此Vue允许使用一个工厂函数的方式进行定义组件。Vue只有在这个组件需要被渲染，并把结果缓存起来供未来重渲染。</p>
<p>​        下面这个简单的例子，表示了第二个参数是一个函数，函数需要使用resolve和reject，表示会以promise进行调用，通过resolve返回渲染对象，荣国reject表示加载失败。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;async-example&#x27;, function (resolve, reject) &#123;</span><br><span class="line">  setTimeout(function () &#123;</span><br><span class="line">    // 向 `resolve` 回调传递组件定义</span><br><span class="line">    resolve(&#123;</span><br><span class="line">      template: &#x27;&lt;div&gt;I am async!&lt;/div&gt;&#x27;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;, 1000)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        一个推荐的做法是将异步组件和 <a target="_blank" rel="noopener" href="https://webpack.js.org/guides/code-splitting/">webpack 的 code-splitting 功能</a>一起配合使用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;async-webpack-example&#x27;, function (resolve) &#123;</span><br><span class="line">  // 这个特殊的 `require` 语法将会告诉 webpack</span><br><span class="line">  // 自动将你的构建代码切割成多个包，这些包</span><br><span class="line">  // 会通过 Ajax 请求加载</span><br><span class="line">  require([&#x27;./my-async-component&#x27;], resolve)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        但是因为我这个异步组件和搭配webpack这个用的比较少，所以在这里就没有进行详细的讲述，就直接贴上Vue的官网链接了。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cn.vuejs.org/v2/guide/components-dynamic-async.html#异步组件</span><br></pre></td></tr></table></figure>



<h3 id="处理加载状态"><a href="#处理加载状态" class="headerlink" title="处理加载状态"></a>处理加载状态</h3><p>​        2.3.0 新增</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">const AsyncComponent = () =&gt; (&#123;</span><br><span class="line">  // 需要加载的组件 (应该是一个 `Promise` 对象)</span><br><span class="line">  component: import(&#x27;./MyComponent.vue&#x27;),</span><br><span class="line">  // 异步组件加载时使用的组件</span><br><span class="line">  loading: LoadingComponent,</span><br><span class="line">  // 加载失败时使用的组件</span><br><span class="line">  error: ErrorComponent,</span><br><span class="line">  // 展示加载时组件的延时时间。默认值是 200 (毫秒)</span><br><span class="line">  delay: 200,</span><br><span class="line">  // 如果提供了超时时间且组件加载也超时了，</span><br><span class="line">  // 则使用加载失败时使用的组件。默认值是：`Infinity`</span><br><span class="line">  timeout: 3000</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<blockquote>
<p>注意如果你希望在 <a target="_blank" rel="noopener" href="https://github.com/vuejs/vue-router">Vue Router</a> 的路由组件中使用上述语法的话，你必须使用 Vue Router 2.4.0+ 版本。</p>
</blockquote>
<h1 id="处理边界情况"><a href="#处理边界情况" class="headerlink" title="处理边界情况"></a>处理边界情况</h1><h2 id="访问元素-amp-组件"><a href="#访问元素-amp-组件" class="headerlink" title="访问元素 &amp; 组件"></a>访问元素 &amp; 组件</h2><h3 id="访问根实例-this-root"><a href="#访问根实例-this-root" class="headerlink" title="访问根实例 this.$root"></a>访问根实例 this.$root</h3><p>​        这个可以通过 <code>this.$root</code>，进行访问。如果是methods里面的方法aa，那么就可以通过 <code>this.$root.aa</code> 进行访问。</p>
<p>​        所有的子组件都可以将这个实例作为一个全局 store 来访问或者使用。</p>
<blockquote>
<p>对于 demo 或非常小型的有少量组件的应用来说这是很方便的。不过这个模式扩展到中大型应用来说就不然了。因此在绝大多数情况下，我们强烈推荐使用 <a target="_blank" rel="noopener" href="https://github.com/vuejs/vuex">Vuex</a> 来管理应用的状态。</p>
</blockquote>
<h3 id="访问父级组件实例"><a href="#访问父级组件实例" class="headerlink" title="访问父级组件实例"></a>访问父级组件实例</h3><p>​        可以通过 $parent 属性来访问一个父组件的实例。<br>​        但是请注意，这样写虽然是可以直接对父组件进行了操作，可以代替props来进行数据的访问，但是却会造成数据的修改时不清楚修改的源头。</p>
<h3 id="访问子组件实例或子元素"><a href="#访问子组件实例或子元素" class="headerlink" title="访问子组件实例或子元素"></a>访问子组件实例或子元素</h3><p>​        可以通过 ref 属性，为子组件赋予一个ID引用。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;base-input ref=&quot;usernameInput&quot;&gt;&lt;/base-input&gt;</span><br><span class="line"></span><br><span class="line">那么父组件就可以通过 this.$refs.usernameInput 来访问子组件了。</span><br></pre></td></tr></table></figure>

<p>​        但是记住，this.$refs，里面存放的只会有属于自己的子组件，以及有可能会有自己的子孙级组件。这个我们一会儿就说。</p>
<p>​        ref同时也可以写在原生的HTML标签上面，for example <code>&lt;input type=&quot;text&quot; ref=&quot;inpu&quot;&gt;</code> 如果写在了原生的HTML上面，我们通过$refs获取时也是一个原生的标签，并且也可以使用方法，比如 <code>focus</code> 等。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;app&quot;&gt;</span><br><span class="line">    &lt;input type=&quot;text&quot; ref=&quot;input&quot;&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">//在父组件的方法里面使用这个便可以调用input的原生focus进行聚焦。</span><br><span class="line">this.$refs.inpu.focus()</span><br></pre></td></tr></table></figure>



<p>关于父组件的 refs 是否会含有子组件，这个应该是在哪个组件被编译就会存在于哪个组件。</p>
<p>​        比如看看下面这个文件的内容。template存在一个插槽和input，然后在使用组件的时候，插槽又是插入了一个input，但是如果我们查看结果，就会发现，插槽所写的ref会存在与父组件，而在template里面所写的，便会存在于子组件。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">template: `&lt;div&gt;&lt;slot&gt;&lt;/slot&gt;&lt;input type=&quot;text&quot; ref=&quot;input&quot;&gt;&lt;/div&gt;`,</span><br><span class="line"></span><br><span class="line">&lt;aaaa ref=&quot;ssss&quot;&gt;</span><br><span class="line">    &lt;input type=&quot;text&quot; ref=&quot;inpu&quot;&gt;</span><br><span class="line">&lt;/aaaa&gt;</span><br></pre></td></tr></table></figure>

<p>​        当 ref 和 v-for 一起使用的时候，ref会包含整个数组。一般来说，refs是一个对象，但是对于使用了v-for的来说，就会变成一个数组，就算是ref使用了v-bind 进行了绑定，也会变为存在不同ref的对象，内部含有数组。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;li :ref=&quot;i&quot; v-for=&quot;i in 10&quot;&gt;&lt;/li&gt;</span><br><span class="line"></span><br><span class="line">1: [li]</span><br><span class="line">2: [li]</span><br><span class="line">3: [li]</span><br><span class="line">4: [li]</span><br><span class="line"></span><br><span class="line">形成的还是数组，虽然数组的长度只有1。</span><br></pre></td></tr></table></figure>



<h3 id="依赖注入"><a href="#依赖注入" class="headerlink" title="依赖注入"></a>依赖注入</h3><p>​        简单来说，就是父子组件可以通过 $parent 来进行访问，但是对于嵌套的情况，会造成 $parent.$parent 那么此时就是依赖注入的时候。</p>
<p>​        这里用到了两个新的实例的选项。 provide &amp; inject</p>
<p><strong>provide</strong> 选项允许我们指定我们想要提供给后代组件的数据/方法。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">provide: function() &#123;</span><br><span class="line">	return &#123;</span><br><span class="line">		get: this.get</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>inject</strong> 在任何后代组件里，我们都可以使用 inject 选项来接收指定的属性进行注入。</p>
<p><strong>例子</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">father</span><br><span class="line">	children</span><br><span class="line">		grandson</span><br><span class="line"></span><br><span class="line">那么此时 grandson要使用 father组件的方法就需要 this.$parent.$parent 来进行调用，但是对于有多层的调用会出现意想不到的问题。</span><br></pre></td></tr></table></figure>

<p>​        使用 provide 和 inject 进行处理，需要记住，这个的调用创建应该是先于data，所以如果当data和inject进行了重合，那么便会出现data覆盖了inject，但是他们都是属于 init injected &amp; reacted 周期。在使用 beforeCreate 之后， 以及 created 之前。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">先使用 provide 进行提供需要给后代的方法和数据。</span><br><span class="line">const app = new Vue(&#123;</span><br><span class="line">	provide() &#123;</span><br><span class="line">		return &#123;</span><br><span class="line">			name: this.output,</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">然后在后代使用 inject 进行注入，注入之后就可以使用 this.name进行使用。</span><br><span class="line">Vue.component(&#x27;xx&#x27;, &#123;</span><br><span class="line">	inject: [&#x27;name&#x27;],</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<h2 id="程序化的事件侦听器"><a href="#程序化的事件侦听器" class="headerlink" title="程序化的事件侦听器"></a>程序化的事件侦听器</h2><p>通过 $on(eventName, eventHandler) 来侦听一个事件。</p>
<p>通过 $once(eventName, eventHandler) 来一次性的侦听一个事件。</p>
<p>通过 $off(eventName, eventHandler)  来停止侦听一个事件。</p>
<p>一般来说是很少进行使用的，但是当你需要在一个组件的实例上手动的侦听事件时，它们便派上了用场。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">mounted() &#123;</span><br><span class="line">	this.pi = new Pi(&#123;&#125;);</span><br><span class="line">&#125;,</span><br><span class="line">beforeDestroy() &#123;</span><br><span class="line">	this.pi.destroy();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>如果使用程序化的侦听器来解决这个问题：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">mounted() &#123;</span><br><span class="line">	const pi = new Pi(&#123;&#125;);</span><br><span class="line">	this.$once(&#x27;hook:beforeDestroy&#x27;, function() &#123;</span><br><span class="line">		pi.destroy();</span><br><span class="line">	&#125;)</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<p><strong>注意</strong>：</p>
<blockquote>
<p>​        Vue 的事件系统不同于浏览器的 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget">EventTarget API</a>。尽管它们工作起来是相似的，但是 <code>$emit</code>、<code>$on</code>, 和 <code>$off</code> 并不是 <code>dispatchEvent</code>、<code>addEventListener</code> 和 <code>removeEventListener</code> 的别名。</p>
</blockquote>
<h2 id="循环引用"><a href="#循环引用" class="headerlink" title="循环引用"></a>循环引用</h2><h3 id="递归组件"><a href="#递归组件" class="headerlink" title="递归组件"></a>递归组件</h3><p>​        组件是可以在他们自己的模板中调用自身的，但是只能通过name选项来做这件事。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">name: &#x27;stack&#x27;,</span><br><span class="line">tempalte: `&lt;div&gt;&lt;stack&gt;&lt;/stack&gt;&lt;/div&gt;`,</span><br></pre></td></tr></table></figure>

<p>​        简单来说就是可以进行递归的循环，所以需要注意，并且发现对于全局注册组件，也可以使用组件名称进行递归组件。</p>
<h3 id="组件之间的循环引用"><a href="#组件之间的循环引用" class="headerlink" title="组件之间的循环引用"></a>组件之间的循环引用</h3><p>​        对于组件之间的相互调用，组件在渲染树中互相为对方的后代和祖先。当通过 Vue.component 全局注册组件的时候，这个悖论将会被解开。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">tree-father</span><br><span class="line">	tree-other</span><br><span class="line">	</span><br><span class="line">tree-other</span><br><span class="line">	tree-father</span><br></pre></td></tr></table></figure>

<p>​        然而，如果你使用一个模块系统依赖/导入组件，则会遇到一个错误。</p>
<p>​        所以此时的解决办法就是：</p>
<ul>
<li><p>将注册事件放入 beforeCreate 进行注册。</p>
<ul>
<li>```<br>beforeCreate() {<pre><code>this.$options.components.ComponentA = require(&#39;./component-a.vue&#39;);
</code></pre>
}<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 或者，在本地进行注册组件的时候，可以使用 webpack 异步 import</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    components: &#123;</span><br><span class="line">    	ComponentA: () =&gt; import(&#x27;./component-a.vue&#x27;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<h2 id="模板定义的代替品"><a href="#模板定义的代替品" class="headerlink" title="模板定义的代替品"></a>模板定义的代替品</h2><h3 id="内联模板"><a href="#内联模板" class="headerlink" title="内联模板"></a>内联模板</h3><p>​        简单来说就是，组件内部的内容将会作为模板，而不是将其视为分布式内容(或者插槽？)。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;my-component inline-template&gt;</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">        &lt;p&gt;These are compiled as the component&#x27;s own template.&lt;/p&gt;</span><br><span class="line">        &lt;p&gt;Not parent&#x27;s transclusion content.&lt;/p&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/my-component&gt;</span><br><span class="line"></span><br><span class="line">Vue.component(&#x27;my-component&#x27;, &#123;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p><strong>注意点</strong>：</p>
<ul>
<li>使用的模板名需要是存在的</li>
<li>如果要使用内联模板，那么对于全局注册的组件时需要的信息可以不需要，比如(template，data，methods等)。</li>
<li>个人感觉这个和 template 的效果很相似。但是注意，使用内联模板也是可以使用data和methods的。所以这个的作用应该是很像 .vue 文件的使用。</li>
</ul>
<h3 id="X-Template"><a href="#X-Template" class="headerlink" title="X-Template"></a>X-Template</h3><p>​        使用 script 脚本，并且将type设置为 text/x-template，然后通过使用 id 来引用模板。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;script type=&quot;text/x-template&quot; id=&quot;hello-world-template&quot;&gt;</span><br><span class="line">  &lt;p&gt;Hello hello hello&lt;/p&gt;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">Vue.component(&#x27;hello-world&#x27;, &#123;</span><br><span class="line">  template: &#x27;#hello-world-template&#x27;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        这些替代模板都是将 模板内部的标签 和 数据 以及操作等进行了分割。</p>
<h2 id="控制更新"><a href="#控制更新" class="headerlink" title="控制更新"></a>控制更新</h2><h3 id="强制更新"><a href="#强制更新" class="headerlink" title="强制更新"></a>强制更新</h3><p>​        使用 $forceUpdate</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">data() &#123;</span><br><span class="line">	return &#123;</span><br><span class="line">		x: [1, 3],</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">this.x[1] = 10;</span><br><span class="line">//此时，虽然数据发生了改变，但是因为vue2的数据响应式无法对数组的直接操作进行通知，所以不会发生更新，那么此时就需要使用 this.$forceUpdate(); 来进行强制更新了。</span><br><span class="line">this.$forceUpdate();</span><br></pre></td></tr></table></figure>



<h3 id="使用-v-once-的廉价静态组件"><a href="#使用-v-once-的廉价静态组件" class="headerlink" title="使用 v-once 的廉价静态组件"></a>使用 v-once 的廉价静态组件</h3><p>​        Vue 渲染纯HTML非常快，但是有时你的组件包含了大量的静态内容。在这些情况下，可以确保只被评估一次。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;terms-of-service&#x27;, &#123;</span><br><span class="line">  template: `</span><br><span class="line">    &lt;div v-once&gt;</span><br><span class="line">      &lt;h1&gt;Terms of Service&lt;/h1&gt;</span><br><span class="line">      ... a lot of static content ...</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">  `</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p><strong>注意</strong>：</p>
<p>尽量不要过度的使用这种模式。除非真的渲染缓慢。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/29/Vue/Vue2%E6%95%99%E7%A8%8B/Vue2-%E6%95%99%E7%A8%8B-%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/29/Vue/Vue2%E6%95%99%E7%A8%8B/Vue2-%E6%95%99%E7%A8%8B-%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8/" class="post-title-link" itemprop="url">Vue-使用-基础使用</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-29 23:15:01" itemprop="dateCreated datePublished" datetime="2021-10-29T23:15:01+08:00">2021-10-29</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/" itemprop="url" rel="index"><span itemprop="name">Vue</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/Vue2%E6%96%87%E6%A1%A3/" itemprop="url" rel="index"><span itemprop="name">Vue2文档</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="Vue的基本使用"><a href="#Vue的基本使用" class="headerlink" title="Vue的基本使用"></a>Vue的基本使用</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">简单入门教程</span><br><span class="line">	https://cn.vuejs.org/v2/guide/</span><br><span class="line">API</span><br><span class="line">	https://cn.vuejs.org/v2/api/</span><br><span class="line"></span><br><span class="line">在这里我就先进行一个简单的教程的学习。不过于深入了解。</span><br></pre></td></tr></table></figure>



<h1 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cn.vuejs.org/v2/guide/index.html</span><br></pre></td></tr></table></figure>



<h2 id="引入"><a href="#引入" class="headerlink" title="引入"></a>引入</h2><p>​        这里我们使用 script 进行引入</p>
<p>​        还可以使用 <strong>npm</strong> 进行下载引入 和 使用 <strong>VueCLI</strong> 脚手架，使用 npm 和 脚手架 的好处是，我们可以方便进行包管理。进行较大型应用时可以进行使用。但是我们这里的主要目的时了解 Vue 的基本使用和Vue 的一些规范，所以就直接使用 <strong>script</strong> 引入。</p>
<p>​        对于 <strong>script</strong> 引入，有两种：</p>
<ul>
<li><p>第一种是直接进行引入。这种是创建了一个全局 Vue 的的实例，可以在后面进行使用，但是不能在前面进行使用。</p>
<ul>
<li>```<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 第二种是使用了 模块化 。 在引用以后，可以在改代码的后面直接进行使用。但是不能在 另外一个 script 标签内部使用，具体的原因是 使用了 module ，这个属于异步加载了。对于script 的异步我们后续在了解。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    &lt;script type=&quot;module&quot;&gt;</span><br><span class="line">      import Vue from &#x27;https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.esm.browser.js&#x27;</span><br><span class="line">      </span><br><span class="line">      Vue.log;</span><br><span class="line">    &lt;/script&gt;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<p>这里我们使用第一种引入。</p>
<h2 id="声明式渲染"><a href="#声明式渲染" class="headerlink" title="声明式渲染"></a>声明式渲染</h2><h3 id="Mustache-语法-valueName"><a href="#Mustache-语法-valueName" class="headerlink" title="Mustache 语法 { { valueName }}"></a>Mustache 语法 { { valueName }}</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;app&quot;&gt;</span><br><span class="line">  &#123; &#123; message &#125;&#125;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- 开发环境版本，包含了有帮助的命令行警告 --&gt;</span><br><span class="line">&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js&quot;&gt;&lt;/script&gt;</span><br><span class="line">&lt;script&gt;</span><br><span class="line">  const app = new Vue(&#123;</span><br><span class="line">    el: &#x27;#app&#x27;,</span><br><span class="line">    data: &#123;</span><br><span class="line">      message: &#x27;test&#x27;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<p>​        这里这个 message 是响应式的。如果我们在浏览器控制台修改了 message 的值，页面也会对应发生变化。里面的原因是使用了 <strong>OBject.defineProperty()</strong> 对于 Vue 的响应式。我们后续在了解 Vue源码的时候在进行讨论。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">app.message = &#x27;a&#x27;;</span><br><span class="line"></span><br><span class="line">页面会同时进行修改。</span><br></pre></td></tr></table></figure>

<p>​        这里我们进行一个分析。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">new Vue，这是一个 new 方法，会返回一个实例，里面的参数是一个对象，对象里面又是很多属性和对象的组成。</span><br><span class="line"></span><br><span class="line">这里出现了。el 和 data。</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">其中el，是你要绑定的元素， 可以是 CSS 选择器，也可以是一个 HTMLElement 实例。</span><br><span class="line">	参考：	https://cn.vuejs.org/v2/api/#el</span><br><span class="line">CSS选择器： #app, .app, div.app ...</span><br><span class="line">HTMLElement实例： </span><br><span class="line">	const span = document.querySelector(&#x27;span.app&#x27;);</span><br><span class="line">	el: span.</span><br><span class="line">其次，对于有多个满足的情况，只会对第一个进行编译。</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">data：</span><br><span class="line">		我们可以看出，这个是一个data的对象。然后是对对象里面的数据进行了一个响应式的处理。然后我们也可以在后续在开发时可以发现，data是一个 返回的对象。这里是因为对象是使用的地址赋值，如果不通过return &#123;&#125;, 会让共同使用的组件会使用相同的数据。但是如果是return &#123;&#125;。那么在每次返回时都会返回一个新的对象出来。而不会共同使用一个对象。 </span><br></pre></td></tr></table></figure>



<h3 id="使用指令绑定-attribute-v-bind"><a href="#使用指令绑定-attribute-v-bind" class="headerlink" title="使用指令绑定 attribute (v-bind)"></a>使用指令绑定 attribute (v-bind)</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;span class=&quot;app&quot; v-bind:title=&quot;message&quot;&gt;</span><br><span class="line">  &#123; &#123; message &#125;&#125;</span><br><span class="line">&lt;/span&gt;</span><br></pre></td></tr></table></figure>

<p>​        这里 v-bind 是 Vue 提供的 <code>attribute </code>。它可以绑定元素原有的 <code>attribute</code> 。这个指令的效果是： 将这个元素节点的 <code>title</code> attribute 和 Vue 实例的 <code>message</code> property 保持一致。</p>
<p>​        可以通过使用 app.message = ‘new’; 可以发现，内容也随之更新。</p>
<h2 id="条件与循环"><a href="#条件与循环" class="headerlink" title="条件与循环"></a>条件与循环</h2><h3 id="v-if"><a href="#v-if" class="headerlink" title="v-if"></a>v-if</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;app-3&quot;&gt;</span><br><span class="line">  &lt;p v-if=&quot;seen&quot;&gt;现在你看到我了&lt;/p&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">var app3 = new Vue(&#123;</span><br><span class="line">  el: &#x27;#app-3&#x27;,</span><br><span class="line">  data: &#123;</span><br><span class="line">    seen: true</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">这里设置的 seen ， 设置为 true ，就会显示。设置为 false ，就不会显示。</span><br></pre></td></tr></table></figure>

<p>​        可以通过设置 v-if 来进行这个标签的显示和隐藏。此外，Vue 也提供一个强大的过渡效果系统，可以在 Vue 插入/更新/移除元素时自动应用<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/transitions.html">过渡效果</a>。</p>
<p>​        这个过渡效果，我们后续在讲。</p>
<p>​        <code>v-if</code> 可以控制一个标签的显示和隐藏，还有 <code>v-show</code> 也有一样的效果。</p>
<p><strong>区别：</strong></p>
<ul>
<li>```<br><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/conditional.html#v-if-vs-v-show">https://cn.vuejs.org/v2/guide/conditional.html#v-if-vs-v-show</a><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* `v-if` 也是**惰性的**：如果在初始渲染时条件为假，则什么也不做——直到条件第一次变为真时，才会开始渲染条件块。</span><br><span class="line">* 相比之下，`v-show` 就简单得多——不管初始条件是什么，元素总是会被渲染，并且只是简单地基于 CSS 进行切换。</span><br><span class="line">* 如果需要非常频繁地切换，则使用 `v-show` 较好；如果在运行时条件很少改变，则使用 `v-if` 较好。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### v-for</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/api/#v-for">https://cn.vuejs.org/v2/api/#v-for</a><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		`v-for` 指令可以绑定数组的数据来渲染一个项目列表：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div id="app-4">
<ol>
  <li v-for="todo in todos">
    { { todo.text }}
  </li>
</ol>
</div></li>
</ul>
<p>var app4 = new Vue({<br>  el: ‘#app-4’,<br>  data: {<br>    todos: [<br>      { text: ‘学习 JavaScript’ },<br>      { text: ‘学习 Vue’ },<br>      { text: ‘整个牛项目’ }<br>    ]<br>  }<br>})</p>
<p>循环。 v-for=”item in items”，  会循环items，赋值给 item。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">**此外：**</span><br><span class="line"></span><br><span class="line">​	在使用 **v-if** 搭配 v-for 时，**v-for** 的优先级会高于 **v-if**。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<li v-for="todo in todos" v-if="todo.flag">
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		在控制台里，输入 `app4.todos.push(&#123; text: &#x27;新项目&#x27; &#125;)`，你会发现列表最后添加了一个新项目。</span><br><span class="line"></span><br><span class="line">**注意：**</span><br><span class="line"></span><br><span class="line">​	这里使用了 **push**， 方式添加了新项目，页面发生了改变，但是如果是 app4.todos[4] = xxx， 这样就不会发生页面的改变，这里是因为Vue 响应式的原因，至于原理，我们后续在讲解。想要提前知道的可以了解一下，Object.defineProperty()。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 处理用户输入</span><br><span class="line"></span><br><span class="line">​		用户和应用的交互，可以使用 **v-on** 指令来添加一个事件的监听器</span><br><span class="line"></span><br><span class="line">这里的 v-on，就代表了 on</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<button v-on:click="reverseMessage">反转消息</button>

<p><button onclick="reverseMessage()">反转消息</button></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>
<p>var app5 = new Vue({<br>  el: ‘#app-5’,<br>  data: {<br>    message: ‘Hello Vue.js!’<br>  },<br>  methods: {<br>    reverseMessage: function () {<br>      this.message = this.message.split(‘’).reverse().join(‘’)<br>    }<br>  }<br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这里新添加了一个 **methods** 的对象，里面存放的是方法。如果是使用 **Vue** 的属性 **attribute**， **v-on** ，来进行的绑定方法，那么就需要将方法写在这个methods 里面。不写在 methods 里面的方法是没有效果的。</span><br><span class="line"></span><br><span class="line">​		其次，这里面建议不要使用 箭头函数，因为箭头函数 的this指向是和 当前的上下文 相关的，所以在箭头函数里面使用不了data的方法。箭头函数的指向是全局。</span><br><span class="line"></span><br><span class="line">​		在这里，我们只需要写上逻辑，不需要操作DOM，这个就是 MVVM 中， Vue 的 VM，我们只需要在 M和V 上进行操作即可。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## v-model 实现双向绑定</span><br><span class="line"></span><br><span class="line">​		v-bind，可以实现单向的绑定，就是指可以通过修改data数据来进行页面的修改。</span><br><span class="line"></span><br><span class="line">​		但是，如果是对于一个 input 的输入框呢？</span><br><span class="line"></span><br><span class="line">​		我们可以将 data 数据绑定到输入框作为一个初始值。</span><br><span class="line"></span><br><span class="line">​		但是我们可以在对输入框进行输入时，同时修改 data 的数据吗。显然是不行的。所以就有了 v-model</span><br><span class="line"></span><br><span class="line">​		v-model ，它可以进行数据的双向绑定，不但用户的输入会修改 data， data 的变化也会影响视图。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<input v-model="message">
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		通过这个我们 可以看出，v-model 没有说使用value，还是什么，但是却有效果，这里是因为 v-model 会根据控件的类型自动选取正确的方法来更新。限制：	input， select， textarea， components</span><br><span class="line"></span><br></pre></td></tr></table></figure>
https://cn.vuejs.org/v2/api/#v-model
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 组件化应用构建</span><br><span class="line"></span><br><span class="line">​		Vue 的另一个重要的概念就是 **组件化** 。几乎任意应用界面都可以抽象为一个组件树。</span><br><span class="line"></span><br><span class="line">​		在 Vue 中注册一个组件</span><br><span class="line"></span><br></pre></td></tr></table></figure>
// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  template: '</li><li>这是个待办项</li>'
})

<p>var app = new Vue(…)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">**示例：**</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div id="app-6">
  <my-item></my-item>
</div>


<p>  Vue.component(‘my-item’, {<br>    template: ‘<li>这是个待办项</li>‘<br>  });</p>
<p>  var app6 = new Vue({ el: ‘#app-6’ })</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">**注意点：**</span><br><span class="line"></span><br><span class="line">* 使用的方式是，需要在 new 的实例的 Vue 的内部进行调用，因为在 实例内部，你写的方式才会被 Vue 所编译，不然是不会被 Vue 编译的。</span><br><span class="line"></span><br><span class="line">* 其次，注册的组件需要在你 new 的实例前面，因为你在编译组件的时候要使用自定义的组件。所以，如果不在之前进行解析的话，就解析不了了。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 组件传值</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div id="app-6">
  <my-item :todo="message"></my-item>
</div>


<p>Vue.component(‘my-item’, {<br>  props: [‘todo’],<br>  template: ‘<li>这是个待办项 { { todo }}</li>‘,<br>});</p>
<p>var app6 = new Vue({<br>  el: ‘#app-6’,<br>  data: {<br>      message: false<br>  }<br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这里， props 是代表了获取到组件属性传递过来的值，在组件使用时，添加属性，这个属性是和 props 里面的名字相等。这里就是 todo， 其次， **:todo**，是一个语法糖，代表了 **v-bind:todo**，所以就会把 message 的值传递给 todo，然后再传递给 my-item。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># Vue实例</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/instance.html">https://cn.vuejs.org/v2/guide/instance.html</a></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 创建一个Vue实例</span><br><span class="line"></span><br><span class="line">​		每个 Vue 应用都是通过用 `Vue` 函数创建一个新的 **Vue 实例**开始的：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>var vm = new Vue({<br>  // 选项<br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		虽然没有完全遵循 [MVVM 模型](https://zh.wikipedia.org/wiki/MVVM)，但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 `vm` (ViewModel 的缩写) 这个变量名表示 Vue 实例。</span><br><span class="line"></span><br><span class="line">​		至于为什么 Vue 没有完全遵循 MVVM 的原因是：Vue 中有一个属性，ref，这个属性可以拿到 DOM 对象，直接操作视图，所以违背了 MVVM。</span><br><span class="line"></span><br><span class="line">​		在创建一个 Vue 实例时，你可以传入一个 [选项对象]([https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E6%95%B0%E6%8D%AE](https://cn.vuejs.org/v2/api/#选项-数据)) (data，methods...)。通过这些选项对象来创建你想要的行为。</span><br><span class="line"></span><br><span class="line">​		一个 Vue 应用由一个通过 `new Vue` 创建的**根 Vue 实例**，以及可选的嵌套的、可复用的组件树组成。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 数据与方法</span><br><span class="line"></span><br><span class="line">​		当一个 Vue 实例被创建时，它将 `data` 对象中的所有的 property 加入到 Vue 的**响应式系统**中。当这些 property 的值发生改变时，视图将会产生“响应”，即匹配更新为新的值。</span><br><span class="line"></span><br><span class="line">​		大致就可以理解为，需要将数据放在了 data 里面，Vue 就会自动创建响应式。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>// 我们的数据对象<br>var data = { a: 1 }</p>
<p>// 该对象被加入到一个 Vue 实例中<br>var vm = new Vue({<br>  data: data<br>})</p>
<p>// 获得这个实例上的 property<br>// 返回源数据中对应的字段<br>vm.a == data.a // =&gt; true</p>
<p>// 设置 property 也会影响到原始数据<br>vm.a = 2<br>data.a // =&gt; 2</p>
<p>// ……反之亦然<br>data.a = 3<br>vm.a // =&gt; 3</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		通过上面我们可以知道，data的数据是直接可以通过 实例的返回来直接获取，数据是直接暴露于实例的顶层。理所当然，methods 的方法也是一样，所以我们会思考，如果方法名和数据名重合会怎么办。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>  var app6 = new Vue({<br>    el: ‘#app-6’,<br>    data: {<br>      message: false<br>    },<br>    methods: {<br>      message() {<br>        console.log(1);<br>      }<br>    },<br>  })</p>
<p>通过上面的案例可以看出，方法名是和 data 名称重合，所以在 data 已经创建了数据之后，方法创建会抛出异常。方法创建失败。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>
<p>  而如果是一个普通的对象，后面的会将前面的覆盖掉。</p>
<p>  let obj = {<br>    a: 1,<br>    a() {<br>      console.log(2);<br>    }<br>  }<br>  console.log(obj);</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		其次</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>使用 vm.b = 1;<br>这种后续添加数据的方式是不会变成响应式的。<br>以及，使用了 Object.freeze() 也会阻止修改现有的 property，也意味着响应系统无法再追踪变化。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		除了数据 property，Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 `$`，以便与用户定义的 property 区分开来。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>var data = { a: 1 }<br>var vm = new Vue({<br>  el: ‘#example’,<br>  data: data<br>})</p>
<p>vm.$data === data // =&gt; true<br>vm.$el === document.getElementById(‘example’) // =&gt; true</p>
<p>// $watch 是一个实例方法<br>vm.$watch(‘a’, function (newValue, oldValue) {<br>  // 这个回调将在 <code>vm.a</code> 改变后调用<br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		你可以在 [API 参考](https://cn.vuejs.org/v2/api/#实例-property)中查阅到完整的实例 property 和方法的列表。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 实例生命周期钩子</span><br><span class="line"></span><br><span class="line">​		生命周期钩子简单来说就是一个回调函数。在 Vue 在执行到每个过程的时候也会执行这些生命周期的钩子。</span><br><span class="line"></span><br><span class="line">​		**举个栗子：**</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>new Vue({<br>  data: {<br>    a: 1<br>  },<br>  created: function () {<br>    // <code>this</code> 指向 vm 实例<br>    console.log(‘a is: ‘ + this.a)<br>  }<br>})<br>// =&gt; “a is: 1”</p>
<p>在 created 钩子可以用来在一个实例被创建之后执行代码：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">**注意：**</span><br><span class="line"></span><br><span class="line">&gt; 不要在选项 property 或回调上使用[箭头函数](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)，比如 `created: () =&gt; console.log(this.a)` 或 `vm.$watch(&#x27;a&#x27;, newValue =&gt; this.myMethod())`。因为箭头函数并没有 `this`，`this` 会作为变量一直向上级词法作用域查找，直至找到为止，经常导致 `Uncaught TypeError: Cannot read property of undefined` 或 `Uncaught TypeError: this.myMethod is not a function` 之类的错误。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 生命周期图示</span><br><span class="line"></span><br><span class="line">![lifecycle](Vue2-教程-基础使用/lifecycle.png)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 模板语法</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/syntax.html">https://cn.vuejs.org/v2/guide/syntax.html</a></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">## 插值</span><br><span class="line"></span><br><span class="line">**文本：**</span><br><span class="line"></span><br><span class="line">​		数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><span>Message: { { msg }}</span></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">这里 msg 会替代为 数据对象的 msg。并且还带有响应式的功能。</span><br><span class="line"></span><br><span class="line">​		通过使用 [v-once 指令](https://cn.vuejs.org/v2/api/#v-once)，你也能执行一次性地插值，当数据改变时，插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><span v-once>这个将不会改变: { { msg }}</span></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**原始HTML：**</span><br><span class="line"></span><br><span class="line">​		双大括号会将数据解释为普通文本，而非 HTML 代码。为了输出真正的 HTML，你需要使用 [`v-html` 指令](https://cn.vuejs.org/v2/api/#v-html)：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><span v-html="rawHtml"></span></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		会将 span 的内容替换为 rawHtml。并且在里面不会解析 proterty。</span><br><span class="line"></span><br><span class="line">&gt; 你的站点上动态渲染的任意 HTML 可能会非常危险，因为它很容易导致 [XSS 攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。请只对可信内容使用 HTML 插值，**绝不要**对用户提供的内容使用插值。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**Attribute：（属性）**</span><br><span class="line"></span><br><span class="line">​		Mustache 语法不能作用在 HTML 标签的属性上，所以要使用 v-bind 指令。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:id="dynamicId"></div>

<p>对于同时使用了 v-bind:id 和 id 的。我们可以发现，谁在后面，其结果就是谁。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		对于布尔值的 attribute，原生的HTML中，只要存在就意味着值为 true，而 v-bind，工作起来当值为 false，null等，甚至不会渲染。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**使用 JavaScript 表达式：**</span><br><span class="line"></span><br><span class="line">​		对于所有的数据绑定，Vue.js 都提供了完全的 JavaScript 表达式支持。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>{ { number + 1 }}</p>
<p>{ { ok ? ‘YES’ : ‘NO’ }}</p>
<p>{ { message.split(‘’).reverse().join(‘’) }}</p>
<div v-bind:id="'list-' + id"></div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 指令</span><br><span class="line"></span><br><span class="line">​		指令 (Directives) 是带有 `v-` 前缀的特殊 attribute。</span><br><span class="line"></span><br><span class="line">**参数：**</span><br><span class="line"></span><br><span class="line">​		一些指令能够接收一个“参数”，在指令名称之后以冒号表示。例如，`v-bind` 指令可以用于响应式地更新 HTML attribute：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<a v-bind:href="url">...</a>

<p>此时这个url是和数据的url是绑定的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		`v-on` 指令，它用于监听 DOM 事件：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><a v-on:click="doSomething">…</a><br>同时也有 mouseover 等等。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">**注意：**</span><br><span class="line"></span><br><span class="line">​		使用 v-on 指令监听 DOM 事件，原生的 onclick 方法会先于 v-on 进行监听，其次这个 v-on 里面的方法，既可以是 methods 的，也可以是 data 的。但是建议写在 methods 中。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div id="app-6">
  <button @click="test1" onclick="console.log(1);">Button</button>
</div>
//其中这里这个 @ 代表了 v-on 的语法糖，我们后续会讲。

<pre><code>let obj = &#123;
message: true,
test1() &#123;
  console.log(3);
&#125;
</code></pre>
<p>  }</p>
<p>  var app6 = new Vue({<br>    el: ‘#app-6’,<br>    data: obj,<br>    methods: {<br>      test() {<br>        console.log(2);<br>      }<br>    }<br>  })</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**动态参数： 2.6.0新增**</span><br><span class="line"></span><br><span class="line">​		可以用方括号括起来的 JavaScript 表达式作为一个指令的参数：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<!--
注意，参数表达式的写法存在一些约束，如之后的“对动态参数表达式的约束”章节所述。
-->
<p>&lt;a v-bind:[attributeName]=”url”&gt; … </p>
<p>&lt;a v-on:[eventName]=”doSomething”&gt; … <br>@[]，也可以。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这里的 `attributeName` 会被作为一个 JavaScript 表达式进行动态求值，求得的值将会作为最终的参数来使用。这里的Vue实例中有 data property attributeName，值为 href，则就等价于 v-bind:href=&quot;url&quot;</span><br><span class="line"></span><br><span class="line">​	**对动态参数的值的约束**</span><br><span class="line"></span><br><span class="line">​		动态参数预期会求出一个字符串，异常情况下值为 `null`。这个特殊的 `null` 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。</span><br><span class="line"></span><br><span class="line">​	**对动态参数表达式的约束**</span><br><span class="line"></span><br><span class="line">​		动态参数表达式有一些语法约束，因为某些字符，如空格和引号，放在 HTML attribute 名里是无效的。例如：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<!-- 这会触发一个编译警告 -->
<p>&lt;a v-bind:[‘foo’ + bar]=”value”&gt; … </p>
<p>使用引号会无法编译。<br>并且使用了空格也会无法编译。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		变通的办法是使用没有空格或引号的表达式，或用计算属性替代这种复杂表达式。</span><br><span class="line"></span><br><span class="line">​		在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板)，还需要避免使用大写字符来命名键名，因为浏览器会把 attribute 名全部强制转为小写：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property，否则代码不会工作。
-->
<p>&lt;a v-bind:[someAttr]=”value”&gt; … </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**修饰符：**</span><br><span class="line"></span><br><span class="line">​		修饰符 (modifier) 是以半角句号 `.` 指明的特殊后缀，用于指出一个指令应该以特殊方式绑定。例如，`.prevent` 修饰符告诉 `v-on` 指令对于触发的事件调用 `event.preventDefault()`：</span><br><span class="line"></span><br><span class="line">​		与之相应的还有 `.laze` `.once` 等等。我们后续进行讲解。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 缩写 语法糖</span><br><span class="line"></span><br><span class="line">**v-bind 缩写**：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<!-- 完整语法 -->
<p><a v-bind:href="url">…</a></p>
<!-- 缩写 -->
<p><a :href="url">…</a></p>
<!-- 动态参数的缩写 (2.6.0+) -->
<p>&lt;a :[key]=”url”&gt; … </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**v-on 缩写：**</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<!-- 完整语法 -->
<p><a v-on:click="doSomething">…</a></p>
<!-- 缩写 -->
<p>&lt;a @click=”doSomething”&gt;…</p>
<!-- 动态参数的缩写 (2.6.0+) -->
<p>&lt;a @[event]=”doSomething”&gt; … </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 计算属性和侦听器</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/computed.html">https://cn.vuejs.org/v2/guide/computed.html</a></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 计算属性</span><br><span class="line"></span><br><span class="line">​		简单来说，就是将逻辑更深层的解耦，比如：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>{ { message.split(‘’).reverse().join(‘’) }}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		在模板中放入太多的逻辑会让模板过重且难以维护。</span><br><span class="line"></span><br><span class="line">​		在这个地方，模板不再是简单的声明式逻辑。你必须看一段时间才能意识到，这里是想要显示变量 `message` 的翻转字符串。当你想要在模板中的多处包含此翻转字符串时，就会更加难以处理。</span><br><span class="line"></span><br><span class="line">​		所以，对于任何复杂逻辑，你都应当使用**计算属性**。</span><br><span class="line"></span><br><span class="line">​		我认为，从一个开发来看，对于一个表达式，如果以后会有多个地方进行相同的逻辑的使用，就应当使用计算属性，方便维护。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 基础例子</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div id="app-6">
  { { message }}
  <br>
  { { reversedMessage }}
</div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>
  const vm = new Vue({
    el: '#app-6',
    data: {
      message: 'true',
    },
    computed: {
      // 计算属性的 getter
      reversedMessage: function () {
        // `this` 指向 vm 实例
        return this.message.split('').reverse().join('')
      }
    },
  })
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这里我们声明了一个计算属性 `reversedMessage`。我们提供的函数将用作 property `vm.reversedMessage` 的 getter 函数</span><br><span class="line"></span><br><span class="line">​		计算属性默认是的方法是一个getter 方法， 就像是使用了 `Object.defineProperty` 的getter一样进行了操作。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 计算属性缓存 VS 方法</span><br><span class="line"></span><br><span class="line">​		我们也可以发现，可以在插值表达式中使用方法来获取同样的效果。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>{ { reversedMessage() }}</p>

<p>methods: {<br>  reversedMessage: function () {<br>    return this.message.split(‘’).reverse().join(‘’)<br>  }<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		首先，对于结果来说是完全相同的。不同的地方在于，**计算属性是基于它们的响应式依赖进行缓存的**。意思就是说，只有相关的响应式依赖发生了改变，他们才会重新求值。没有发生改变，多次使用计算属性会立即返回之前的结果。</span><br><span class="line"></span><br><span class="line">​		**举个栗子：**</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div id="app-6">
  { { message }}
  <br>
  { { reversedMessage }}
  <br>
  { { reversedMessage }}
  <br>
  { { reversedMessage }}
</div>


<p>  const vm = new Vue({<br>    el: ‘#app-6’,<br>    data: {<br>      message: ‘true’,<br>    },<br>    computed: {<br>      // 计算属性的 getter<br>      reversedMessage: function () {<br>        // <code>this</code> 指向 vm 实例<br>        console.log(1);<br>        return this.message.split(‘’).reverse().join(‘’)<br>      }<br>    },<br>  })</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		我这里使用了很多个插值表达式，但是发现控制台的输出，只有一个，这里代表了后续是直接使用的之前的计算结果。</span><br><span class="line"></span><br><span class="line">​		其次，在值发生变化之时，也只输出了一次。因此计算属性的缓存效果则比方法有了更好的性能。</span><br><span class="line"></span><br><span class="line">​		当然，如果不希望有缓存的存在，可以使用方法来替代。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 计算属性 VS 侦听属性</span><br><span class="line"></span><br><span class="line">​		Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动：**侦听属性**。 `watch`  。</span><br><span class="line"></span><br><span class="line">​		侦听属性 和 计算属性的不同</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>watch: {<br>  firstName: function (val) {<br>      this.fullName = val + ‘ ‘ + this.lastName<br>  },<br>  lastName: function (val) {<br>      this.fullName = this.firstName + ‘ ‘ + val<br>  }<br>},<br>computed: {<br>  fullName: function () {<br>      return this.firstName + ‘ ‘ + this.lastName<br>  }<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		从上面可以看出，侦听属性(watch)的特点是，当一个属性发生改变后，调用的方法。</span><br><span class="line"></span><br><span class="line">​		其次，需要对其进行初始化，因为在最开始侦听属性不会进行调用。</span><br><span class="line"></span><br><span class="line">​		最后，这个侦听属性的执行时机，我们通过一个简单的死循环就可以看出。侦听属性在 DOM 的变化之前。但是处于值的变化之后。起码下面这个情况满足。这个说法。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>watch: {<br>  message: function (val) {<br>  console.log(this.message);<br>  while (true) {<br>      console.log(this.message);<br>  }<br>      this.reversedMessage = val + ‘ — ‘;<br>  }<br>},</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 计算属性的setter</span><br><span class="line"></span><br><span class="line">​		默认计算属性只有 getter，不过在需要时你也可以提供一个 setter。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>computed: {<br>  fullName: {<br>    // getter<br>    get: function () {<br>      return this.firstName + ‘ ‘ + this.lastName<br>    },<br>    // setter<br>    set: function (newValue) {<br>      var names = newValue.split(‘ ‘)<br>      this.firstName = names[0]<br>      this.lastName = names[names.length - 1]<br>    }<br>  }<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		在运行 `vm.fullName = &#x27;John Doe&#x27;` 时，setter 会被调用，`vm.firstName` 和 `vm.lastName` 也会相应地被更新。</span><br><span class="line"></span><br><span class="line">​		当然，如果你这样写，只能说你是小机灵鬼了，一直调用了 setter 方法导致溢出。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>set: function (newValue) {<br>  console.log(newValue);<br>  this.reversedMessage += ‘1’;<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		同时我们也可以使用一些简单的方式查看这个 setter 的执行时机。通过下面这个方式，我们发现了，setter 的执行在值的变化之前。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>computed: {<br>  // 计算属性的 getter<br>  reversedMessage: {<br>    get: function () {<br>      // <code>this</code> 指向 vm 实例<br>      console.log(1);<br>      return this.message.split(‘’).reverse().join(‘’)<br>    },<br>    set: function (newValue) {<br>      console.log(this.reversedMessage, newValue);<br>      while (true) {<br>      console.log(this.reversedMessage);<br>    };<br>  }<br>},</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 侦听器</span><br><span class="line"></span><br><span class="line">&gt; ​		虽然计算属性在大多数情况下更合适，但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 `watch` 选项提供了一个更通用的方法，来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时，这个方式是最有用的。</span><br><span class="line"></span><br><span class="line">​		简单来说就是对于一个异步，和一个开销大的操作时，监听器比较合适。</span><br><span class="line"></span><br><span class="line">​		异步操作，限制访问频率(防抖)，设置中间状态等。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># Class 与 Style 绑定</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/class-and-style.html">https://cn.vuejs.org/v2/guide/class-and-style.html</a></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		在将 `v-bind` 用于 `class` 和 `style` 时，Vue.js 做了专门的增强。表达式结果的类型除了字符串之外，还可以是对象或数组。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 绑定 HTML Class</span><br><span class="line"></span><br><span class="line">### 对象语法</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>v-bind:class=”{ active: isActive, ‘text-danger’: hasError }”</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这样，就会根据 后面的真值来判断前面这个类是否能存在。并且这里 active 是一个字符串，就算这个 active 和后面的一个 data 数据重名，最终渲染的还是一个字符串。如何能让 active 也变成一个变量类型，</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:class="{ [message]: flag }"></div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这里使用了动态绑定，所以 message  会从data里面进行查找。找不到则为 undefined 的字符串。并且可以使用 .undefined 来进行操作。对于不是字符串的，会转为字符串处理。</span><br><span class="line"></span><br><span class="line">​		并且绑定的数据对象不必内联定义在模板里。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:class="classObject"></div>

<p>data: {<br>  classObject: {<br>    active: true,<br>    ‘text-danger’: false<br>  }<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		如果写在 data 里面，我还不知道如何将类名动态绑定。并且后面的 true 和 false 都是写死的那种，只能在后续使用方法改变。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<pre><code>computed: &#123;
  classObject: function () &#123;
    return &#123;
      [this.message]: this.flag
    &#125;
  &#125;
&#125;,
</code></pre>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		如果写在计算属性里面，那么类名和真值都可以通过 this 进行获取。类名还是一样通过 [] 获取。不加上就会直接当成一个字符串。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 数组语法</span><br><span class="line"></span><br><span class="line">​		我们可以把一个数组传给 `v-bind:class`，以应用一个 class 列表</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:class="[activeClass, errorClass]"></div>

<p>data: {<br>  activeClass: ‘active’,<br>  errorClass: ‘text-danger’<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		对于不是字符串的，不会被显示，需要是字符串类型才会显示。</span><br><span class="line"></span><br><span class="line">​		同时，也能写三元表达式</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		在数组语法中也可以使用对象语法：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 在组件上</span><br><span class="line"></span><br><span class="line">​		当在一个自定义组件上使用 `class` property 时，这些 class 将被添加到该组件的根元素上面。这个元素上已经存在的 class 不会被覆盖。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})

<p><my-component class="baz boo"></my-component></p>
<p class="foo bar baz boo">Hi</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		在渲染的时候，重复的类名不会被消除。当然，最终的渲染结果还是看CSS的权重级别。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 绑定内联样式</span><br><span class="line"></span><br><span class="line">### 对象语法</span><br><span class="line"></span><br><span class="line">​		`v-bind:style` 的对象语法十分直观——看着非常像 CSS，但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case，记得用引号括起来) 来命名</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

<div v-bind:style="{ color: activeColor, 'font-size': fontSize + 'px' }"></div>

<p>data: {<br>  activeColor: ‘red’,<br>  fontSize: 30<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		当然也能绑定到一个样式对象。大致还是和上面的要求一样。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 数组语法</span><br><span class="line"></span><br><span class="line">​		`v-bind:style` 的数组语法可以将多个样式对象应用到同一个元素上：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-bind:style="[activeColor]">123</div>

<p>activeColor: {<br>    fontSize: ‘30px’<br>},</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		当然，也能将其作为一个数组加对象整合为一个返回值，绑定到一个样式对象。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 自动添加前缀</span><br><span class="line"></span><br><span class="line">​		当 `v-bind:style` 使用需要添加[浏览器引擎前缀](https://developer.mozilla.org/zh-CN/docs/Glossary/Vendor_Prefix)的 CSS property 时，如 `transform`，Vue.js 会自动侦测并添加相应的前缀。</span><br><span class="line"></span><br><span class="line">​		其次，对于使用了 v-bind:style 和 style 的，会以 v-bind:style 为主。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 多重值 （2.3.0）</span><br><span class="line"></span><br><span class="line">​		从 2.3.0 起你可以为 `style` 绑定中的 property 提供一个包含多个值的数组，常用于提供多个带前缀的值</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这样写只会渲染数组中最后一个被浏览器支持的值。在本例中，如果浏览器支持不带浏览器前缀的 flexbox，那么就只会渲染 `display: flex`。</span><br><span class="line"></span><br><span class="line">​		**意思就是说**，对于这样的一个值的数组，我们会从后往前进行赋值，直到遇到浏览器可以支持的值，例如本例来说，先判断，flex，再判断 -ms-flexbox，最后再判断 -webkit-box。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 条件渲染</span><br><span class="line"></span><br></pre></td></tr></table></figure>
https://cn.vuejs.org/v2/guide/conditional.html
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## v-if</span><br><span class="line"></span><br><span class="line">​		`v-if` 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。</span><br><span class="line"></span><br><span class="line">​		也可以用 `v-else` 添加一个“else 块”：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 在 `&lt;template&gt;` 元素上使用 `v-if` 条件渲染分组</span><br><span class="line"></span><br><span class="line">​		因为 `v-if` 是一个指令，所以必须将它添加到一个元素上。但是如果想切换多个元素呢？此时可以把一个 `&lt;template&gt;` 元素当做不可见的包裹元素，并在上面使用 `v-if`。最终的渲染结果将不包含 `&lt;template&gt;` 元素。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这里很好理解。首先 v-if 只能添加到一个元素上，所以我们使用了一个元素进行了包裹，然后这个 template 的一个特点就是不会显示，例如</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<template>
    <div>123</div>
</template>

<p>最终的显示结果就是</p>
<div>123</div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		所以这个的好处在于，既能产生包裹，还能不将其 DOM 的结构进行变化。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### v-else</span><br><span class="line"></span><br><span class="line">​		你可以使用 `v-else` 指令来表示 `v-if` 的“else 块”</span><br><span class="line"></span><br><span class="line">​		`v-else` 元素必须紧跟在带 `v-if` 或者 `v-else-if` 的元素的后面，否则它将不会被识别。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### v-else-if（2.1.0）</span><br><span class="line"></span><br><span class="line">​		`v-else-if`，顾名思义，充当 `v-if` 的“else-if 块”，可以连续使用</span><br><span class="line"></span><br><span class="line">​		类似于 `v-else`，`v-else-if` 也必须紧跟在带 `v-if` 或者 `v-else-if` 的元素之后。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else>Not A/B/C</div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 用 `key` 管理可复用的元素</span><br><span class="line"></span><br><span class="line">​		Vue 会尽可能高效地渲染元素，通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外，还有其它一些好处。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		那么在上面的代码中切换 `loginType` 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素，`&lt;input&gt;` 不会被替换掉——仅仅是替换了它的 `placeholder`。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">​		对于上述的代码，切换了 input  的输入框，但是却对于 value 值没有发生改变。但是如果我们会发现对于类名，style等属性是会发生改变。我们同时也可以知道 value 是input输入框的值，如果是对于 DOM 元素，可以通过 value 进行获取，但是在这里，虽然使用了 value 的属性，但是只要进行输入了，value 的值也不起效果。</span><br><span class="line"></span><br><span class="line">​		但是我们同时也发现了，再切换之后，DOM 的指向没有改变。并且也发现了 value 的值在控制台的输出是有变化的。只是对于输入框的内容没有变化。个人猜测，这里input的输入和value 其实中间不是完全直接对应。输入框显示的 value 只是作为了一个最初值。但是内部的value已经发生了变化。</span><br><span class="line"></span><br><span class="line">​		当然解决这个方法很简单。</span><br><span class="line"></span><br><span class="line">*  Vue 为你提供了一种方式来表达“这两个元素是完全独立的，不要复用它们”。只需添加一个具有唯一值的 `key` attribute 即可</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    &lt;input placeholder=&quot;Enter your username&quot; key=&quot;username-input&quot;&gt;</span><br></pre></td></tr></table></figure>

<ul>
<li><p>这里，只需要 key 值不同即可。并且发现加了 key 值之后， DOM 获取的元素已经不会根据你的按钮发生变化，并且值也不会发生变化了，因为已经不是一个 input 框了，就算是换回来也不是一个了，因为 v-if 是直接修改了 DOM 树。</p>
</li>
<li><p>```</p>
<template v-if="loginType === 'username'">
  <label>Username</label>
  <input key="a" class="a" style="color: red; font-size: 20px" placeholder="Enter your username" value="1">
</template>
<template v-else>
  <label>Email</label>
  <input key="b" class="b" placeholder="Enter your email address" value="2">
</template>


<p>记住，这个需要放在 vue实例之后，应该是因为 template 的原因。<br>const a = document.querySelector(‘input.a’),</p>
<pre><code>b = document.querySelector(&#39;input.b&#39;);
</code></pre>
<p>function c() {<br>  console.log(a);<br>  console.log(a.value);<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 当然，还可以使用 v-model 将数据进行绑定，那么input输入框的显示也会跟数据有关了。并且 v-model 是进行的复用。因为 DOM 的输出是会发生变化的。并且输入框和data数据是实时绑定了的。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## v-show</span><br><span class="line"></span><br><span class="line">​		另一个用于根据条件展示元素的选项是 `v-show` 指令。用法大致一样</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 v-show="ok">Hello!</h1>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		同的是带有 `v-show` 的元素始终会被渲染并保留在 DOM 中。`v-show` 只是简单地切换元素的 CSS property `display`。</span><br><span class="line"></span><br><span class="line">&gt; 注意，`v-show` 不支持 `&lt;template&gt;` 元素，也不支持 `v-else`。</span><br><span class="line"></span><br><span class="line">​		v-show 不支持 template 元素，意思就是说，你在 template 元素上使用 v-show，不管是 true 还是 false，template 都会显示在页面上，而如果你使用v-if就会发现，结果是不一样的。</span><br><span class="line"></span><br><span class="line">​		v-show 不支持 v-else，就如字面上来说，不支持的意思。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## v-if VS v-show</span><br><span class="line"></span><br><span class="line">​		`v-if` 是“真正”的条件渲染，因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。</span><br><span class="line"></span><br><span class="line">​		`v-if` 也是**惰性的**：如果在初始渲染时条件为假，则什么也不做——直到条件第一次变为真时，才会开始渲染条件块。</span><br><span class="line"></span><br><span class="line">​		相比之下，`v-show` 就简单得多——不管初始条件是什么，元素总是会被渲染，并且只是简单地基于 CSS 进行切换。</span><br><span class="line"></span><br><span class="line">​		一般来说，`v-if` 有更高的切换开销，而 `v-show` 有更高的初始渲染开销。因此，如果需要非常频繁地切换，则使用 `v-show` 较好；如果在运行时条件很少改变，则使用 `v-if` 较好。</span><br><span class="line"></span><br><span class="line">​		**简单概括：**</span><br><span class="line"></span><br><span class="line">* **v-if** 是会直接和 DOM 树相关。而 **v-show** 只是简单的使用了 display:none，和渲染树相关。</span><br><span class="line">* 所以 v-if 对于切换会产生高开销，因为每次都会进行 DOM 的修改。而 v-show 会产生初始渲染的高开销，因为不管是否显示都会渲染。</span><br><span class="line">* 所以，对于频繁切换使用 v-show，对于很少改变使用 v-if。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## v-if 和 v-for 一起使用</span><br><span class="line"></span><br><span class="line">&gt; **不推荐**同时使用 `v-if` 和 `v-for`。请查阅[风格指南](https://cn.vuejs.org/v2/style-guide/#避免-v-if-和-v-for-用在一起-必要)以获取更多信息。</span><br><span class="line"></span><br><span class="line">​		当 `v-if` 与 `v-for` 一起使用时，`v-for` 具有比 `v-if` 更高的优先级。请查阅[列表渲染指南](https://cn.vuejs.org/v2/guide/list.html#v-for-with-v-if)以获取详细信息。</span><br><span class="line"></span><br><span class="line">​		当它们处于同一节点，`v-for` 的优先级比 `v-if` 更高，这意味着 `v-if` 将分别重复运行于每个 `v-for` 循环中。当你只想为*部分*项渲染节点时，这种优先级的机制会十分有用。</span><br><span class="line"></span><br><span class="line">​		通过查看了 风格指南，主要说几点：</span><br><span class="line"></span><br><span class="line">* 避免一起使用</span><br><span class="line"></span><br><span class="line">* 对于需要过滤一个列表中的项目，采用计算属性</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    v-for=&quot;user in users&quot; v-if=&quot;user.isActive&quot;</span><br><span class="line">    </span><br><span class="line">    可以对 user 使用一个计算属性 activeUser 使用filter过滤后返回</span><br><span class="line">    v-for=&quot;user in activeUsers&quot;</span><br><span class="line">    </span><br><span class="line">    computed: &#123;</span><br><span class="line">    	activeUsers: function() &#123;</span><br><span class="line">    		return this.users.filter((user) =&gt; user.isActive);</span><br><span class="line">    	&#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></li>
<li><p>对于会直接应该被隐藏的列表，将 v-if 放在上层，不要在每次循环的时候判断</p>
<ul>
<li>```<br>v-for=”user in users” v-if=”shouldShowUsers”shouldShowUsers 这是对一个 users 进行的判断，只要为 false，所有的 users都不会显示，所以这个建议放在上层<br>v-if=”shouldShowUsers”<pre><code>v-for=&quot;user in users&quot;
</code></pre>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 列表渲染</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/list.html">https://cn.vuejs.org/v2/guide/list.html</a><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 用 v-for 把一个数组对应为一组元素</span><br><span class="line"></span><br><span class="line">​		我们可以用 `v-for` 指令基于一个数组来渲染一个列表。`v-for` 指令需要使用 `item in items` 形式的特殊语法，其中 `items` 是源数据数组，而 `item` 则是被迭代的数组元素的**别名**。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ul id="example-1">
<li v-for="item in items" :key="item.message">

</li>
</ul></li>
</ul>
</li>
</ul>
<p>items: [<br>  { message: ‘Foo’ },<br>  { message: ‘Bar’ }<br>]</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		`v-for` 还支持一个可选的第二个参数，即当前项的索引。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<li v-for="(item, index) in items">
     -  - 
</li>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		index 从0开始。</span><br><span class="line"></span><br><span class="line">​		你也可以用 `of` 替代 `in` 作为分隔符，因为它更接近 JavaScript 迭代器的语法</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-for="item of items"></div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 在 `v-for` 里使用对象</span><br><span class="line"></span><br><span class="line">​		你也可以用 `v-for` 来遍历一个对象的 property。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<li v-for="value in object">
    
</li>

<p>object: {<br>  title: ‘How to do lists in Vue’,<br>  author: ‘Jane Doe’,<br>  publishedAt: ‘2016-04-10’<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		你也可以提供第二个的参数为 property 名称 (也就是键名)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-for="(value, name) in object">
  : 
</div>

<p>title: How to do lists in Vue</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		还可以用第三个参数作为索引</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-for="(value, name, index) in object">

<p>0<br>1<br>2</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&gt; ​		在遍历对象时，会按 `Object.keys()` 的结果遍历，但是**不能**保证它的结果在不同的 JavaScript 引擎下都一致。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**注意：**</span><br><span class="line"></span><br><span class="line">* 如果 v-for 里面是一个正整数n，那么将会变成 1~n，如果是一个小数，会报错。</span><br><span class="line">  * 因为这个方法是会对其进行length操作，所以对于非正整数将出问题。</span><br><span class="line">* 如果v-for里面是一个字符串，那么将会把字符串挨个字符输出。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 维护状态</span><br><span class="line"></span><br><span class="line">​		当 Vue 正在更新使用 `v-for` 渲染的元素列表时，它默认使用“就地更新”的策略。如果数据项的顺序被改变，Vue 将不会移动 DOM 元素来匹配数据项的顺序，而是就地更新每个元素，并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 `track-by=&quot;$index&quot;`。</span><br><span class="line"></span><br><span class="line">​		**简单来说就是**，发现了变化，不会查看是否是有匹配的 DOM，而是直接将原来位置上的DOM进行改变。比如如果只是位置发生了改变，如果使用默认的方式，那么就会挨着将DOM进行修改，但是如果使用了key来进行维护，那么会查看是否有key值存在的，有的话就会直接使用key的DOM进行维护。没有再创建。</span><br><span class="line"></span><br><span class="line">​		这个默认的模式是高效的，但是**只适用于不依赖子组件状态或临时 DOM 状态 (例如：表单输入值) 的列表渲染输出**。</span><br><span class="line"></span><br><span class="line">​		**这里给的意思就是说**，如果对于依赖了子组件话，那么进行修改的时候需要耗费大量的时间，所以需要进行一些判断来处理要使用什么方法。</span><br><span class="line"></span><br><span class="line">​		为了给 Vue 一个提示，以便它能跟踪每个节点的身份，从而重用和重新排序现有元素，你需要为每项提供一个唯一 `key` attribute</span><br><span class="line"></span><br><span class="line">​		就是说可以使用key来进行定位。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<div v-for="item in items" v-bind:key="item.id">
  <!-- 内容 -->
</div>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		建议尽可能在使用 `v-for` 时提供 `key` attribute，除非遍历输出的 DOM 内容非常简单，或者是刻意依赖默认行为以获取性能上的提升。</span><br><span class="line"></span><br><span class="line">​		因为它是 Vue 识别节点的一个通用机制，`key` 并不仅与 `v-for` 特别关联。后面我们将在指南中看到，它还具有其它用途。</span><br><span class="line"></span><br><span class="line">​		其次对于key值，不要使用index下标进行赋值，因为如果你对数组进行了变化，位置变化等，可能下标也会发生改变，这样可能还会降低性能。</span><br><span class="line"></span><br><span class="line">&gt; ​		不要使用对象或数组之类的非基本类型值作为 `v-for` 的 `key`。请用字符串或数值类型的值。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 数组更新检测</span><br><span class="line"></span><br><span class="line">### 变更方法</span><br><span class="line"></span><br><span class="line">​		因为Vue的响应式是相对于Object.defineProperty的使用。所以Vue对数组的处理方式是，对方法进行了包裹，所以使用了数组的方法也会触发视图的更新。</span><br><span class="line"></span><br><span class="line">​		这些方法包括了</span><br><span class="line"></span><br></pre></td></tr></table></figure>
push，pop，shift，unshift，splice，sort，reverse
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 替换数组</span><br><span class="line"></span><br><span class="line">​		变更方法，顾名思义，会变更调用了这些方法的原始数组。相比之下，也有非变更方法，例如 `filter()`、`concat()` 和 `slice()`。它们不会变更原始数组，而**总是返回一个新数组**。当使用非变更方法时，可以用新数组替换旧数组。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		简单来说，上面的变更方法在调用之后是会变化原数组的。但是我们也有不会变更原数组的方法。所以对于这些不会变更原数组的方法，我们可以选择直接进行重新赋值。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
items = newItems
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		我们可以发现对数组直接进行赋值也触发了视图的变化。因为我们对items这个数组也进行了监听。地址的改变也触发了视图的变化，同理，对于一个对象也是一样的。</span><br><span class="line"></span><br><span class="line">​		你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是，事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法，所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。</span><br><span class="line"></span><br><span class="line">&gt; ​		由于 JavaScript 的限制，Vue **不能检测**数组和对象的变化。[深入响应式原理](https://cn.vuejs.org/v2/guide/reactivity.html#检测变化的注意事项)中有相关的讨论。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 显示过滤/排序后的结果</span><br><span class="line"></span><br><span class="line">​		有时，我们想要显示一个数组经过过滤或排序后的版本，而不实际变更或重置原始数据。在这种情况下，可以创建一个计算属性，来返回过滤或排序后的数组。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<li v-for="n in evenNumbers"></li>

<p>computed: {<br>  evenNumbers: function () {<br>    return this.numbers.filter(function (number) {<br>      return number % 2 === 0<br>    })<br>    }<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		对于计算属性不适合的情况下，比如是循环嵌套了循环，此时对于循环内层，用不了计算属性，可以使用方法</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ul v-for="set in sets">
  <li v-for="n in even(set)"></li>
</ul>

<p>even: function (numbers) {<br>  return numbers.filter(function (number) {<br>      return number % 2 === 0<br>  })<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		当然，你可能会想着，我对这个内层也加一个计算属性啊，但是，是没有效果的，简单来说就是因为就近原则，一个是循环的set，一个计算属性的set，他会先找循环的set。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 在 v-for 里使用值范围</span><br><span class="line"></span><br><span class="line">​		`v-for` 也可以接受整数。在这种情况下，它会把模板重复对应次数。</span><br><span class="line"></span><br><span class="line">​		对于字符串则会将字符进行循环。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 在 \&lt;template&gt; 上使用 v-for</span><br><span class="line"></span><br><span class="line">​		类似于 `v-if`，你也可以利用带有 `v-for` 的 `&lt;template&gt;` 来循环渲染一段包含多个元素的内容。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 在组件上使用 `v-for`</span><br><span class="line"></span><br><span class="line">​		在自定义组件上，你可以像在任何普通元素上一样使用 `v-for`。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><my-component v-for="item in items" :key="item.id"></my-component></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		**2.2.0+ 的版本里，当在组件上使用 `v-for` 时，`key` 现在是必须的。**</span><br><span class="line"></span><br><span class="line">​		然而，任何数据都不会被自动传递到组件里，因为组件有自己独立的作用域。为了把迭代数据传递到组件里，我们要使用 prop。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ul>
  <li is="todo-item" v-for="(todo, index) in todos" v-bind:key="todo.id" v-bind:title="todo.title" v-on:remove="todos.splice(index, 1)"></li>
</ul>

<p>Vue.component(‘todo-item’, {<br>  template: ‘<br>    <li><br>      Vue-使用-基础使用<br>      <button v-on:click="$emit(\'remove\')">Remove</button><br>    </li><br>  ‘,<br>  props: [‘title’]<br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&gt; ​		注意这里的 `is=&quot;todo-item&quot;` attribute。这种做法在使用 DOM 模板时是十分必要的，因为在 `&lt;ul&gt;` 元素内只有 `&lt;li&gt;` 元素会被看作有效内容。这样做实现的效果与 `&lt;todo-item&gt;` 相同，但是可以避开一些潜在的浏览器解析错误。查看 [DOM 模板解析说明](https://cn.vuejs.org/v2/guide/components.html#解析-DOM-模板时的注意事项) 来了解更多信息。</span><br><span class="line"></span><br><span class="line">​		简单来说，ul 元素内只有li元素被看作有效，我们使用is方法进行了替换，这样重点可以避开潜在的浏览器解析错误。当然这是一个Vue的方法。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 事件处理</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/events.html">https://cn.vuejs.org/v2/guide/events.html</a></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 监听事件</span><br><span class="line"></span><br><span class="line">​		可以用 `v-on` 指令监听 DOM 事件，并在触发时运行一些 JavaScript 代码。对应的语法糖，`@`</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><button v-on:click="counter += 1">Add 1</button></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 事件处理方法</span><br><span class="line"></span><br><span class="line">​		然而许多事件处理逻辑会更为复杂，所以直接把 JavaScript 代码写在 `v-on` 指令中是不可行的。因此 `v-on` 还可以接收一个需要调用的方法名称。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<!-- `greet` 是在下面定义的方法名 -->
<p><button v-on:click="greet">Greet</button></p>
<p>// 在 <code>methods</code> 对象中定义方法<br>methods: {<br>  greet: function (event) {<br>    // <code>this</code> 在方法里指向当前 Vue 实例<br>    alert(‘Hello ‘ + this.name + ‘!’)<br>    // <code>event</code> 是原生 DOM 事件<br>    if (event) {<br>        alert(event.target.tagName)<br>    }<br>  }<br>}</p>
<p>// 也可以用 JavaScript 直接调用方法<br>vm.greet() // =&gt; ‘Hello Vue.js!’</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 内联处理器中的方法</span><br><span class="line"></span><br><span class="line">​		除了直接绑定到一个方法，也可以在内联 JavaScript 语句中调用方法：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><button v-on:click="say('hi')">Say hi</button></p>
<p>methods: {<br>  say: function (message) {<br>      alert(message)<br>  }<br>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 `$event` 把它传入方法</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**对于event方法的使用：**</span><br><span class="line"></span><br><span class="line">* 如果方法是不带参数的，可以直接使用event，或者参数上加上event</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    &lt;button @click=&quot;change&quot;&gt;button&lt;/button&gt;</span><br><span class="line">    </span><br><span class="line">    change(event) &#123;console.log(event);&#125;,</span><br><span class="line">    change() &#123;console.log(event);&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><p>不同点：</p>
<ul>
<li>如果使用了 @click=change()，加上了括号，对于第一个，传参event的，无法使用，第二个可以使用。</li>
</ul>
</li>
<li><p>当然我们也可以使用 $event 来传递这个参数。</p>
</li>
</ul>
<h2 id="事件修饰符"><a href="#事件修饰符" class="headerlink" title="事件修饰符"></a>事件修饰符</h2><p>​        在事件处理程序中调用 <code>event.preventDefault()</code> 或 <code>event.stopPropagation()</code> 是非常常见的需求。尽管我们可以在方法中轻松实现这点，但更好的方式是：方法只有纯粹的数据逻辑，而不是去处理 DOM 事件细节。</p>
<p>​        首先默认使用的click方法就是冒泡类型。</p>
<p>​        常见的事件修饰符</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">.stop</span><br><span class="line">	阻止事件的冒泡</span><br><span class="line">.prevent</span><br><span class="line">	阻止事件的默认行为，对于在父元素使用了阻止默认行为，子元素的默认行为都会被阻止。</span><br><span class="line">.capture</span><br><span class="line">	转为捕获事件监听，事件的监听顺序是 root --&gt; target 捕获， target --&gt; root 冒泡</span><br><span class="line">.self</span><br><span class="line">	只有目标元素是自身才会触发，对于子元素的点击也不会触发。</span><br><span class="line">.once	/ 2.1.4 新增</span><br><span class="line">	只触发一次。</span><br><span class="line">.passive / 2.3.0 新增</span><br><span class="line">	</span><br></pre></td></tr></table></figure>

<p>​        不像其它只能对原生的 DOM 事件起作用的修饰符，<code>.once</code> 修饰符还能被用到自定义的<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-custom-events.html">组件事件</a>上</p>
<blockquote>
<p>​        使用修饰符时，顺序很重要；相应的代码会以同样的顺序产生。因此，用 <code>v-on:click.prevent.self</code> 会阻止<strong>所有的点击</strong>，而 <code>v-on:click.self.prevent</code> 只会阻止对元素自身的点击。</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;div @click.prevent.self=&quot;change&quot;&gt;</span><br><span class="line">  &lt;a href=&quot;#1&quot; @click=&quot;change1&quot;&gt;321&lt;/a&gt;</span><br><span class="line">  &lt;div @click=&quot;change1&quot;&gt;123&lt;/div&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">&lt;div @click.self.prevent=&quot;change&quot;&gt;</span><br><span class="line">  &lt;a href=&quot;#1&quot; @click=&quot;change1&quot;&gt;321&lt;/a&gt;</span><br><span class="line">  &lt;div @click=&quot;change1&quot;&gt;123&lt;/div&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>​        <strong>热知识</strong>：父元素阻止了默认行为会影响到子元素。</p>
<p>​        <strong>热知识2：</strong> click方法会先于默认行为执行。并且要冒泡结束了之后才会执行。</p>
<p>​        Vue 还对应 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters"><code>addEventListener</code> 中的 <code>passive</code> 选项</a>提供了 <code>.passive</code> 修饰符。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 --&gt;</span><br><span class="line">&lt;!-- 而不会等待 `onScroll` 完成  --&gt;</span><br><span class="line">&lt;!-- 这其中包含 `event.preventDefault()` 的情况 --&gt;</span><br><span class="line">&lt;div v-on:scroll.passive=&quot;onScroll&quot;&gt;...&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>​        他这里是这样说，貌似意思是说，默认行为会先触发，然后再触发 onScroll 的方法，但是我对一个。a标签进行操作的时候发现是先输出，然后在跳转，对于一个scroll行为的测试从肉眼上看也是和a标签一样，当然这个滚动的行为可能才滚1帧就开始触发了循环，导致卡帧也有可能。所以我现在不知道如何判断。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&lt;div @click=&quot;change&quot;&gt;</span><br><span class="line">	&lt;a href=&quot;#1&quot; @click.passive=&quot;change1&quot;&gt;321&lt;/a&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">methods: &#123;</span><br><span class="line">  change() &#123;</span><br><span class="line">    console.log(&#x27;father&#x27;);</span><br><span class="line">    let date = new Date().getTime() + 1000;</span><br><span class="line">    while (date &gt; new Date()) &#123;</span><br><span class="line"></span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;,</span><br><span class="line">  change1() &#123;</span><br><span class="line">  	console.log(&#x27;children&#x27;);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        发现是先输出控制台，然后url再变化的。</p>
<p>​        并且如果父元素使用了 prevent，子元素的passive无效，passive只能让本元素上的prevent无效。</p>
<p>​        这个 <code>.passive</code> 修饰符尤其能够提升移动端的性能。 </p>
<p>​        </p>
<h2 id="按键修饰符"><a href="#按键修饰符" class="headerlink" title="按键修饰符"></a>按键修饰符</h2><p>​        在监听键盘事件时，我们经常需要检查详细的按键。Vue 允许为 <code>v-on</code> 在监听键盘事件时添加按键修饰符</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` --&gt;</span><br><span class="line">&lt;input v-on:keyup.enter=&quot;submit&quot;&gt;</span><br></pre></td></tr></table></figure>



<h3 id="按键码"><a href="#按键码" class="headerlink" title="按键码"></a>按键码</h3><blockquote>
<p>​        <code>keyCode</code> 的事件用法<a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode">已经被废弃了</a>并可能不会被最新的浏览器支持。</p>
</blockquote>
<p>​        使用 <code>keyCode</code> attribute 也是允许的：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;input v-on:keyup.13=&quot;submit&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        为了在必要的情况下支持旧浏览器，Vue 提供了绝大多数常用的按键码的别名：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.enter	.tab	.delete (捕获“删除”和“退格”键)	.esc	.space	.up	.down	.left	.right</span><br></pre></td></tr></table></figure>

<blockquote>
<p>​        有一些按键 (<code>.esc</code> 以及所有的方向键) 在 IE9 中有不同的 <code>key</code> 值, 如果你想支持 IE9，这些内置的别名应该是首选。</p>
</blockquote>
<p>​        你还可以通过全局 <code>config.keyCodes</code> 对象<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/api/#keyCodes">自定义按键修饰符别名</a>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// 可以使用 `v-on:keyup.f1`</span><br><span class="line">Vue.config.keyCodes.f1 = 112</span><br></pre></td></tr></table></figure>

<p>​        按键别名可以进行覆盖，当然这个不建议这样写已经存在的。</p>
<p><strong>注意：</strong></p>
<p>​        按键别名不要使用大写，因为大写的在 <code>&lt;input v-on:keyup.enter=&quot;submit&quot;&gt; </code>，在这里会转为小写，所以无法使用成功。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;text&quot; @keyup.A=&quot;change&quot;&gt;</span><br><span class="line"></span><br><span class="line">Vue.config.keyCodes.A = 97;</span><br></pre></td></tr></table></figure>



<h2 id="系统修饰键"><a href="#系统修饰键" class="headerlink" title="系统修饰键"></a>系统修饰键</h2><p>​        可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。(2.1.0新增)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.ctrl</span><br><span class="line">.alt</span><br><span class="line">.shift</span><br><span class="line">.meta</span><br><span class="line">	就是Windows键盘上的那个Windows图标按钮。mac同理</span><br></pre></td></tr></table></figure>

<blockquote>
<p>​        注意：在 Mac 系统键盘上，meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上，meta 对应实心宝石键 (◆)。在其他特定键盘上，尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品，比如 Knight 键盘、space-cadet 键盘，meta 被标记为“META”。在 Symbolics 键盘上，meta 被标记为“META”或者“Meta”。</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- Alt + C --&gt;</span><br><span class="line">&lt;input v-on:keyup.alt.67=&quot;clear&quot;&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- Ctrl + Click --&gt;</span><br><span class="line">&lt;div v-on:click.ctrl=&quot;doSomething&quot;&gt;Do something&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<ul>
<li>使用系统修饰键对于 @keyup.67.ctrl 和 @keyup.ctrl.67 是一样的。不会有先后顺序。</li>
<li>请注意修饰键与常规按键不同，在和 <code>keyup</code> 事件一起用时，事件触发时修饰键必须处于按下状态。换句话说，只有在按住 <code>ctrl</code> 的情况下释放其它按键，才能触发 <code>keyup.ctrl</code>。而单单释放 <code>ctrl</code> 也不会触发事件。如果你想要这样的行为，请为 <code>ctrl</code> 换用 <code>keyCode</code>：<code>keyup.17</code>。17代表了ctrl</li>
<li><strong>@keyup.17.67</strong> 这个代表了按这两个其中一个都有效</li>
<li>系统修饰键可以使用多个。</li>
</ul>
<h3 id="exact-修饰符（2-5-0新增）"><a href="#exact-修饰符（2-5-0新增）" class="headerlink" title=".exact 修饰符（2.5.0新增）"></a>.exact 修饰符（2.5.0新增）</h3><p>​        <code>.exact</code> 修饰符允许你控制由精确的系统修饰键组合触发的事件。</p>
<p>​        <strong>作用</strong>：用于<strong>精确</strong>控制系统修饰键按键的修饰符。主要在于精确两个字。并且是对系统修饰键起作用的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;text&quot; @keyup.a.up.exact=&quot;change&quot;&gt;</span><br><span class="line">	这个里面没有系统修饰键，监听了两个按键，最终效果：没有什么区别，唯一的区别就是如果此时你按了系统修饰键将不会触发。</span><br><span class="line">	所以这个代表了&lt;!-- 没有任何系统修饰键被按下的时候才触发 --&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;text&quot; @keyup.ctrl.up.exact=&quot;change&quot;&gt;</span><br><span class="line">	这个里面存在了系统修饰键 ctrl，所以效果就是必须按了 ctrl才会有用，（当然这个是系统修饰键的效果），.exact修饰符 的效果就是，系统修饰键必须只按了ctrl才有用。精确。加上系统修饰键。</span><br><span class="line">	其次.exact 修饰符没有位置的要求，和系统修饰键一样没有位置要求，</span><br><span class="line">	然后就是对于 &lt;input type=&quot;text&quot; @keyup.exact.ctrl.up.a=&quot;change&quot;&gt; 我们可以发现， 一个exact修饰符，一个ctrl系统修饰键，两个普通按键修饰符。所以最终的效果是，有且只有按了ctrl键，加上普通按键修饰符的其中一个就行。</span><br><span class="line">	&lt;!-- 有且只有 Ctrl 被按下的时候才触发 --&gt;</span><br></pre></td></tr></table></figure>



<h3 id="鼠标按钮修饰符（2-2-0新增）"><a href="#鼠标按钮修饰符（2-2-0新增）" class="headerlink" title="鼠标按钮修饰符（2.2.0新增）"></a>鼠标按钮修饰符（2.2.0新增）</h3><p>​        这些修饰符会限制处理函数仅响应特定的鼠标按钮。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">.left</span><br><span class="line">.right</span><br><span class="line">.middle</span><br></pre></td></tr></table></figure>

<p>​        用于点击事件，对于keyup事件不起作用，当然对于系统修饰键和.exact修饰符没有这些要求。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;div @click.middle.ctrl.exact=&quot;change&quot;&gt;321&lt;/div&gt;</span><br><span class="line">	要求是 ctrl键 + 鼠标中键才会触发。</span><br></pre></td></tr></table></figure>



<h2 id="为什么要在-HTML-中监听事件"><a href="#为什么要在-HTML-中监听事件" class="headerlink" title="为什么要在 HTML 中监听事件"></a>为什么要在 HTML 中监听事件</h2><p>​        你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心，因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上，它不会导致任何维护上的困难。实际上，使用 <code>v-on</code> 有几个好处：</p>
<ol>
<li>扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。</li>
<li>因为你无须在 JavaScript 里手动绑定事件，你的 ViewModel 代码可以是非常纯粹的逻辑，和 DOM 完全解耦，更易于测试。</li>
<li>当一个 ViewModel 被销毁时，所有的事件处理器都会自动被删除。你无须担心如何清理它们。</li>
</ol>
<p><strong>概括就是说</strong>：虽然是在html中进行的使用监听，但是真正的处理是绑定在VM上的。其次对于v-on的好处：1.能够一眼看出方法。2.和DOM完全解耦。3.当一个VM被销毁时，所有的事件会自动清除。</p>
<h1 id="表单输入绑定"><a href="#表单输入绑定" class="headerlink" title="表单输入绑定"></a>表单输入绑定</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cn.vuejs.org/v2/guide/forms.html</span><br></pre></td></tr></table></figure>



<h2 id="基础用法"><a href="#基础用法" class="headerlink" title="基础用法"></a>基础用法</h2><p>​        你可以用 <code>v-model</code> 指令在表单 <code>&lt;input&gt;</code>、<code>&lt;textarea&gt;</code> 及 <code>&lt;select&gt;</code> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;input v-model=&quot;message&quot; placeholder=&quot;edit me&quot;&gt;</span><br><span class="line">这里，我是用 v-model，并没有绑定给value，但是会自动选取正确的方法进行更新。</span><br></pre></td></tr></table></figure>



<p><strong>注意：</strong></p>
<ul>
<li>v-model 会忽略元素自带的value，checked等属性，而是使用Vue实例的数据作为来源。</li>
</ul>
<p>​        <code>v-model</code> 在内部为不同的输入元素使用不同的 property 并抛出不同的事件。</p>
<ul>
<li>text 和 textarea 元素使用 <code>value</code> property 和 <code>input</code> 事件；</li>
<li>checkbox 和 radio 使用 <code>checked</code> property 和 <code>change</code> 事件；（使用的是真值方式truth）</li>
<li>select 字段将 <code>value</code> 作为 prop 并将 <code>change</code> 作为事件。</li>
</ul>
<blockquote>
<p>​        对于需要使用<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E8%BE%93%E5%85%A5%E6%B3%95">输入法</a> (如中文、日文、韩文等) 的语言，你会发现 <code>v-model</code> 不会在输入法组合文字过程中得到更新。如果你也想处理这个过程，请使用 <code>input</code> 事件。</p>
</blockquote>
<p>​        你在输入框输入加上一个input事件的监听的时候就会发现。如果在输入的时候使用了中文，虽然在按键的时候发生了input事件，但是v-model的值并没有得到更新。</p>
<p>​        但是如果是普通的input输入框的监听则会发生更新。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;text&quot; v-model=&quot;string&quot; @input=&quot;change&quot; oninput=&quot;console.log(&#x27;event:    &#x27; + event.target.value);&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        并且在进行了空格之后会发生多次的更新。</p>
<h3 id="文本-和-多行文本"><a href="#文本-和-多行文本" class="headerlink" title="文本 和 多行文本"></a>文本 和 多行文本</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;text&quot; v-model=&quot;message&quot;&gt;</span><br><span class="line">&lt;textarea v-model=&quot;message&quot;&gt;&lt;/textarea&gt;</span><br></pre></td></tr></table></figure>

<p>​        在文本区域插值 (<code>&lt;textarea&gt;&#123;&#123;text&#125;&#125;&lt;/textarea&gt;</code>) 并不会生效，应用 <code>v-model</code> 来代替。</p>
<h3 id="复选框"><a href="#复选框" class="headerlink" title="复选框"></a>复选框</h3><p>​        单个复选框，直接布尔值进行的判断，对于不是布尔类型的使用了truth方式。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;checkbox&quot; id=&quot;checkbox&quot; v-model=&quot;checked&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        对于多个复选框</p>
<p>​        注意：复选框和单选框是通过value进行判断。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;checkbox&quot; id=&quot;jack&quot; value=&quot;Jack&quot; v-model=&quot;checkedNames&quot;&gt;</span><br><span class="line">&lt;label for=&quot;jack&quot;&gt;Jack&lt;/label&gt;</span><br><span class="line">&lt;input type=&quot;checkbox&quot; id=&quot;john&quot; value=&quot;John&quot; v-model=&quot;checkedNames&quot;&gt;</span><br><span class="line">&lt;label for=&quot;john&quot;&gt;John&lt;/label&gt;</span><br><span class="line">&lt;input type=&quot;checkbox&quot; id=&quot;mike&quot; value=&quot;Mike&quot; v-model=&quot;checkedNames&quot;&gt;</span><br><span class="line">&lt;label for=&quot;mike&quot;&gt;Mike&lt;/label&gt;</span><br></pre></td></tr></table></figure>

<p>​        <del>我们可以发现，这里没有对复选框进行分组，正常的情况下，复选框需要进行name的分组，相同的name为一组。这个好像是对单选框的。复选框应该本来就可以不用分组？</del></p>
<p>​        对于一个复选框，如果绑定了v-model，但是value不绑定，那么点击一个就是点击多个。因为没有使用value属性，值为null，所以所有为null都会被同步变化。</p>
<p>​        同时，如果多选的复选框，但是绑定的属性不是一个数组那么最终也会变为全部都会出现相同的变化。 <code>checkedNames: 1,</code> </p>
<h3 id="单选按钮"><a href="#单选按钮" class="headerlink" title="单选按钮"></a>单选按钮</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;radio&quot; name=&quot;aa&quot; id=&quot;jack&quot; value=&quot;Jack&quot; v-model=&quot;checkedNames&quot;&gt;</span><br><span class="line">&lt;label for=&quot;jack&quot;&gt;Jack&lt;/label&gt;</span><br><span class="line">&lt;input type=&quot;radio&quot; name=&quot;cc&quot; id=&quot;john&quot; value=&quot;John&quot; v-model=&quot;checkedNames&quot;&gt;</span><br><span class="line">&lt;label for=&quot;john&quot;&gt;John&lt;/label&gt;</span><br><span class="line">&lt;input type=&quot;radio&quot; name=&quot;aa&quot; id=&quot;mike&quot; value=&quot;Mike&quot; v-model=&quot;checkedNames&quot;&gt;</span><br><span class="line">&lt;label for=&quot;mike&quot;&gt;Mike&lt;/label&gt;</span><br></pre></td></tr></table></figure>

<p>​        在这里，我将name进行不同的划分，但是可以发现他们还是一组的成员。</p>
<p>​        <del>所以我们可以这样认为，使用了v-model之后，name也会绑定为这个属性的名称，所以你自己定义的属性名称是没有作用的。</del>（注意：这里不是说，绑定的是v-model属性的名称，而是说，name的绑定和v-model的属性相关了。但是值不知道是什么。）</p>
<p>​        <strong>注意：</strong> 首先我们可以测试出来，name的属性还是没有改变，因为如果添加了一个 相同name，但是没有使用v-model的，会出现竞争。</p>
<p>​        对于单选按钮，<strong>没有使用value的</strong>，那么v-model绑定的属性取出来的值是空。就是那种什么都没有的空。<strong>并且name属性默认不同</strong>。</p>
<p>​        如果自己定义了name属性，那么会以自己定义的为准。但是如果使用了value，搭配了v-model，对于同value，不同name，两个都选上。 <del>那么name属性还是以v-model为准（是指相同的v-model有相同的name）。</del></p>
<p>​        并且，如果value相等，name不等，那么点击时，都会一起变化。如果name相等了，那么点击时点击那个就是哪个，但是value的值不变，并且对于初始化来说，是根据value的值来进行的变化，所以会以最后一个为准。</p>
<p>​        这里有很多问题，但是这些都是可以手动避免的。大概知道就行。我也被自己扯蒙了。</p>
<h3 id="选择框"><a href="#选择框" class="headerlink" title="选择框"></a>选择框</h3><p>​        单选时，直接绑定一个值即可</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;select v-model=&quot;selected&quot;&gt;</span><br><span class="line">  &lt;option disabled value=&quot;&quot;&gt;请选择&lt;/option&gt;</span><br><span class="line">  &lt;option&gt;A&lt;/option&gt;</span><br><span class="line">  &lt;option&gt;B&lt;/option&gt;</span><br><span class="line">  &lt;option&gt;C&lt;/option&gt;</span><br><span class="line">&lt;/select&gt;</span><br><span class="line">&lt;span&gt;Selected: &#123;&#123; selected &#125;&#125;&lt;/span&gt;</span><br></pre></td></tr></table></figure>

<p>​        我们也可以发现，对于使用option的时候，可以不添加value属性，此时绑定的值就是内容。</p>
<p><strong>注意：</strong>如果没有规定 value 属性，选项的值将设置为 &lt;option&gt; 标签中的内容。</p>
<p><strong>注意：</strong></p>
<blockquote>
<p>​        如果 <code>v-model</code> 表达式的初始值未能匹配任何选项，<code>&lt;select&gt;</code> 元素将被渲染为“未选中”状态。在 iOS 中，这会使用户无法选择第一个选项。因为这样的情况下，iOS 不会触发 change 事件。因此，更推荐像上面这样提供一个值为空的禁用选项。</p>
</blockquote>
<p>​        当然这个我不清楚，毕竟我没有IOS。。。。。。</p>
<p>​        多选时就是绑定一个数组</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;select v-model=&quot;selected&quot; multiple style=&quot;width: 50px;&quot;&gt;</span><br><span class="line">  &lt;option&gt;A&lt;/option&gt;</span><br><span class="line">  &lt;option&gt;B&lt;/option&gt;</span><br><span class="line">  &lt;option&gt;C&lt;/option&gt;</span><br><span class="line">&lt;/select&gt;</span><br><span class="line">&lt;br&gt;</span><br><span class="line">&lt;span&gt;Selected: &#123;&#123; selected &#125;&#125;&lt;/span&gt;</span><br></pre></td></tr></table></figure>

<p>​        首先，select多选框的属性 multiple，其次就是使用的数组了。</p>
<p>​        对于不是使用数组的，将不会初始化成功，但是在后续的赋值还是会转化为数组。</p>
<p>​        当然，对于 option 也可以使用v-for进行动态渲染。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;option v-for=&quot;item in options&quot;&gt;&#123;&#123; item &#125;&#125;&lt;/option&gt;</span><br></pre></td></tr></table></figure>



<h2 id="值绑定"><a href="#值绑定" class="headerlink" title="值绑定"></a>值绑定</h2><p>​        对于单选按钮，复选框及选择框的选项，<code>v-model</code> 绑定的值通常是静态字符串 (对于复选框也可以是布尔值)：</p>
<p>​        但是有时我们可能想把值绑定到 Vue 实例的一个动态 property 上，这时可以用 <code>v-bind</code> 实现，并且这个 property 的值可以不是字符串。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 当选中时，`picked` 为字符串 &quot;a&quot; --&gt;</span><br><span class="line">&lt;input type=&quot;radio&quot; v-model=&quot;picked&quot; value=&quot;a&quot;&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 当选中时，`picked` 为a 的值 --&gt;</span><br><span class="line">&lt;input type=&quot;radio&quot; v-model=&quot;picked&quot; :value=&quot;a&quot;&gt;</span><br></pre></td></tr></table></figure>



<h3 id="复选框-1"><a href="#复选框-1" class="headerlink" title="复选框"></a>复选框</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;input</span><br><span class="line">  type=&quot;checkbox&quot;</span><br><span class="line">  v-model=&quot;toggle&quot;</span><br><span class="line">  true-value=&quot;yes&quot;</span><br><span class="line">  false-value=&quot;no&quot;</span><br><span class="line">&gt;</span><br><span class="line"></span><br><span class="line">// 当选中时</span><br><span class="line">vm.toggle === &#x27;yes&#x27;</span><br><span class="line">// 当没有选中时</span><br><span class="line">vm.toggle === &#x27;no&#x27;</span><br></pre></td></tr></table></figure>

<p>​        针对多个复选框。其值还是为value值，如果没有value，其值就是null</p>
<blockquote>
<p>​        这里的 <code>true-value</code> 和 <code>false-value</code> attribute 并不会影响输入控件的 <code>value</code> attribute，因为浏览器在提交表单时并不会包含未被选中的复选框。如果要确保表单中这两个值中的一个能够被提交，(即“yes”或“no”)，请换用单选按钮。</p>
</blockquote>
<p>​        所以这个 true/false value 是单选时比较有用。</p>
<h3 id="单选按钮-1"><a href="#单选按钮-1" class="headerlink" title="单选按钮"></a>单选按钮</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=&quot;radio&quot; v-model=&quot;pick&quot; v-bind:value=&quot;a&quot;&gt;</span><br><span class="line"></span><br><span class="line">// 当选中时</span><br><span class="line">vm.pick === vm.a</span><br></pre></td></tr></table></figure>

<p>​    </p>
<h3 id="选择框的选项"><a href="#选择框的选项" class="headerlink" title="选择框的选项"></a>选择框的选项</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;select v-model=&quot;selected&quot;&gt;</span><br><span class="line">    &lt;!-- 内联对象字面量 --&gt;</span><br><span class="line">  &lt;option v-bind:value=&quot;&#123; number: 123 &#125;&quot;&gt;123&lt;/option&gt;</span><br><span class="line">&lt;/select&gt;</span><br><span class="line"></span><br><span class="line">// 当选中时</span><br><span class="line">typeof vm.selected // =&gt; &#x27;object&#x27;</span><br><span class="line">vm.selected.number // =&gt; 123</span><br></pre></td></tr></table></figure>

<p>​        通过这个我们可以看出，这个是可以使用对象的，同理，我们对于其他的选项框也可以使用对象的形式。</p>
<h2 id="修饰符"><a href="#修饰符" class="headerlink" title="修饰符"></a>修饰符</h2><h3 id="lazy"><a href="#lazy" class="headerlink" title=".lazy"></a>.lazy</h3><p>​        在默认情况下，<code>v-model</code> 在每次 <code>input</code> 事件触发后将输入框的值与数据进行同步 (除了<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/forms.html#vmodel-ime-tip">上述</a>输入法组合文字时)。你可以添加 <code>lazy</code> 修饰符，从而转为在 <code>change</code> 事件_之后_进行同步</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 在“change”时而非“input”时更新 --&gt;</span><br><span class="line">&lt;input v-model.lazy=&quot;msg&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        在输入之后使用回车，便是change事件。</p>
<h3 id="number"><a href="#number" class="headerlink" title=".number"></a>.number</h3><p>​        如果想自动将用户的输入值转为数值类型，可以给 <code>v-model</code> 添加 <code>number</code> 修饰符</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;input v-model.number=&quot;age&quot; type=&quot;number&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        无法输入字符串。</p>
<p>​        这通常很有用，因为即使在 <code>type=&quot;number&quot;</code> 时，HTML 输入元素的值也总会返回字符串。如果这个值无法被 <code>parseFloat()</code> 解析，则会返回原始的值。</p>
<p>​        如何出现无法解析的情况，因为可以输入 e，+，-等，所以还是可以无法解析，问题在于无法解析输出的类型是字符串，但是貌似内容为’’，</p>
<h3 id="trim"><a href="#trim" class="headerlink" title=".trim"></a>.trim</h3><p>​        如果要自动过滤用户输入的首尾空白字符，可以给 <code>v-model</code> 添加 <code>trim</code> 修饰符：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;input v-model.trim=&quot;msg&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        没啥说的。就是字符串的 trim 方法。这个方法的使用是返回一个新的。</p>
<h2 id="在组件上使用-v-model-（2-2-0-新增）"><a href="#在组件上使用-v-model-（2-2-0-新增）" class="headerlink" title="在组件上使用 v-model （2.2.0+ 新增）"></a>在组件上使用 v-model （2.2.0+ 新增）</h2><p>​        HTML 原生的输入元素类型并不总能满足需求。幸好，Vue 的组件系统允许你创建具有完全自定义行为且可复用的输入组件。这些输入组件甚至可以和 <code>v-model</code> 一起使用！</p>
<p>​        要了解更多，请参阅组件指南中的<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-v-model">自定义输入组件</a>。</p>
<p>​        讲真，没有看懂。</p>
<p>​        我们通过跳转，看到了自定义组件的 v-model 我只能大概知道</p>
<p>​        一个组件上的 <code>v-model</code> 默认会利用名为 <code>value</code> 的 prop 和名为 <code>input</code> 的事件，但是像单选框、复选框等类型的输入控件可能会将 <code>value</code> attribute 用于<a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Value">不同的目的</a>。<code>model</code> 选项可以用来避免这样的冲突</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;base-checkbox&#x27;, &#123;</span><br><span class="line">  model: &#123;</span><br><span class="line">    prop: &#x27;checked&#x27;,</span><br><span class="line">    event: &#x27;change&#x27;</span><br><span class="line">  &#125;,</span><br><span class="line">  props: &#123;</span><br><span class="line">    checked: Boolean</span><br><span class="line">  &#125;,</span><br><span class="line">  template: `</span><br><span class="line">    &lt;input</span><br><span class="line">      type=&quot;checkbox&quot;</span><br><span class="line">      v-bind:checked=&quot;checked&quot;</span><br><span class="line">      v-on:change=&quot;$emit(&#x27;change&#x27;, $event.target.checked)&quot;</span><br><span class="line">    &gt;</span><br><span class="line">  `</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">使用v-model时</span><br><span class="line">&lt;base-checkbox v-model=&quot;lovingVue&quot;&gt;&lt;/base-checkbox&gt;</span><br></pre></td></tr></table></figure>

<p>​        这里因为使用了v-model进行传值，所以使用了model: {}，设置了prop的名字，然后在props进行使用，此时传递的值就和父组件的 lovingVue 进行了绑定。然后通过事件$emit， change进行的提交。</p>
<p>​        这里的 <code>lovingVue</code> 的值将会传入这个名为 <code>checked</code> 的 prop。同时当 <code>&lt;base-checkbox&gt;</code> 触发一个 <code>change</code> 事件并附带一个新的值的时候，这个 <code>lovingVue</code> 的 property 将会被更新。</p>
<blockquote>
<p>​        注意你仍然需要在组件的 <code>props</code> 选项里声明 <code>checked</code> 这个 prop。</p>
</blockquote>
<h1 id="组件基础"><a href="#组件基础" class="headerlink" title="组件基础"></a>组件基础</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cn.vuejs.org/v2/guide/components.html</span><br></pre></td></tr></table></figure>



<h2 id="基本示例"><a href="#基本示例" class="headerlink" title="基本示例"></a>基本示例</h2><p>​        这里有一个 Vue 组件的示例</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">// 定义一个名为 button-counter 的新组件</span><br><span class="line">Vue.component(&#x27;button-counter&#x27;, &#123;</span><br><span class="line">  data: function () &#123;</span><br><span class="line">    return &#123;</span><br><span class="line">      count: 0</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  template: &#x27;&lt;button v-on:click=&quot;count++&quot;&gt;You clicked me &#123;&#123; count &#125;&#125; times.&lt;/button&gt;&#x27;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        组件是可复用的 Vue 实例，且带有一个名字：在这个例子中是 <code>&lt;button-counter&gt;</code>。我们可以在一个通过 <code>new Vue</code> 创建的 Vue 根实例中，把这个组件作为自定义元素来使用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;components-demo&quot;&gt;</span><br><span class="line">  &lt;button-counter&gt;&lt;/button-counter&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>​        当然注意上面这个组件的定义顺序要在你的Vue实例之前。因为编译问题，如果在之后的话就不会被编译了。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Vue.componnet(&#x27;button&#x27;, &#123; &#125;);</span><br><span class="line"></span><br><span class="line">const vm = new Vue();</span><br></pre></td></tr></table></figure>

<p>​        因为组件是可复用的 Vue 实例，所以它们与 <code>new Vue</code> 接收相同的选项，例如 <code>data</code>、<code>computed</code>、<code>watch</code>、<code>methods</code> 以及生命周期钩子等。仅有的例外是像 <code>el</code> 这样根实例特有的选项。</p>
<h2 id="组件的复用"><a href="#组件的复用" class="headerlink" title="组件的复用"></a>组件的复用</h2><p>​        组件在被创建之后，可以被多次使用。</p>
<h3 id="data必须是一个函数"><a href="#data必须是一个函数" class="headerlink" title="data必须是一个函数"></a>data必须是一个函数</h3><p>​        当我们定义这个 <code>&lt;button-counter&gt;</code> 组件时，你可能会发现它的 <code>data</code> 并不是像这样直接提供一个对象</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;button&#x27;, &#123;</span><br><span class="line">	data: &#123;</span><br><span class="line">		return &#123;</span><br><span class="line">			</span><br><span class="line">		&#125;;</span><br><span class="line">	&#125;,</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">const vm = new Vue(&#123;</span><br><span class="line">	data: &#123;</span><br><span class="line">		</span><br><span class="line">	&#125;,</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        当然如果你不这样写也不会报错，但是这样会有一个问题，那就是所以这个组件都会使用同一个对象的数据，一个发生了改变，所有都会发生改变。所以就是用了函数，这个会每次都调用了一次函数，形成一个新的作用域位置。</p>
<p>​        这个就是使用了闭包的方法，当然你可能在想，是不是可以利用这个闭包，然后既能让数据不同步，又能让部分数据进行同步。当然，我没有解决掉。因为首先我们可以知道闭包的使用方式。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">function Fn() &#123;</span><br><span class="line">	return fn() &#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">let fn = Fn();</span><br><span class="line">这个时候使用fn，就可以使用闭包。但是data是重复的创建Fn(). 所以每次都还是会创建新东西。</span><br></pre></td></tr></table></figure>

<p>​        所以我现在不知道如何使用闭包的方式，当然，我们可以将方法写在全局，然后再组件里进行闭包。还是可以的。</p>
<h2 id="组件的组织"><a href="#组件的组织" class="headerlink" title="组件的组织"></a>组件的组织</h2><p>​        为了能在模板中使用，这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型：<strong>全局注册</strong>和<strong>局部注册</strong>。至此，我们的组件都只是通过 <code>Vue.component</code> 全局注册的</p>
<p>​        全局注册的组件可以用在其被注册之后的任何 (通过 <code>new Vue</code>) 新创建的 Vue 根实例，也包括其组件树中的所有子组件的模板中。</p>
<p>​        局部注册的方式就是先将内容对象赋值给了一个变量，然后通过使用变量来进行注册。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">let ComponentA = &#123;  &#125;</span><br><span class="line"></span><br><span class="line">new Vue(&#123;</span><br><span class="line">	el: &#x27;#xx&#x27;,</span><br><span class="line">	components: &#123;</span><br><span class="line">		&#x27;component-a&#x27;: ComponentA,</span><br><span class="line">	&#125;,</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>



<h2 id="通过Prop向子组件传递数据"><a href="#通过Prop向子组件传递数据" class="headerlink" title="通过Prop向子组件传递数据"></a>通过Prop向子组件传递数据</h2><p>​        简单来说，就是写在props属性里面的会添加到属性，父组件在调用子组件时，可以通过在标签里添加对应的属性，属性里面的值将会传递给子组件。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;blog-post&#x27;, &#123;</span><br><span class="line">  props: [&#x27;title&#x27;],</span><br><span class="line">  template: &#x27;&lt;h3&gt;&#123;&#123; title &#125;&#125;&lt;/h3&gt;&#x27;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">&lt;blog-post title=&quot;My journey with Vue&quot;&gt;&lt;/blog-post&gt;</span><br></pre></td></tr></table></figure>

<p>​        当然对于这个props，也有另一个写法，props使用对象，对象里面又是一个对象，default代表了默认值，type代表了类型，当然也有其他属性。但是我们后面在详细了解。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">props: &#123;</span><br><span class="line">  &#x27;title&#x27;: &#123;</span><br><span class="line">    default: &#x27;123&#x27;,</span><br><span class="line">    type: String</span><br><span class="line">  &#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;blog-post title=&quot;My journey with Vue&quot;&gt;&lt;/blog-post&gt;</span><br><span class="line">&lt;blog-post&gt;&lt;/blog-post&gt;</span><br></pre></td></tr></table></figure>

<p>​        当然这个自定的属性attribute，也是可以使用v-bind: 来动态绑定。当然我们也可以使用v-model，但是这里也有其他的问题，具体后续在了解。</p>
<p>​        传递的属性也能是对象，对于一些应该属于统一对象的，可以将其化为一个对象进行传递。</p>
<h2 id="单个根元素"><a href="#单个根元素" class="headerlink" title="单个根元素"></a>单个根元素</h2><p>​        简单来说，就是在创建时，只能以一个根元素。如果根元素不止一个就会报错</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;div&gt;&lt;/div&gt;</span><br><span class="line">&lt;div&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>​        上面这个写法就会报错，但是下面这个写法。将所有的元素都放在了一个根元素的下级。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;div&gt;</span><br><span class="line">  &lt;div&gt;&lt;/div&gt;</span><br><span class="line">  &lt;div&gt;&lt;/div&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<p>​        这里的原因。我不清楚，只能说在Vue里面如果使用了下面这个写法时，可以知道，只会将第一个进行Vue的渲染，第二个将不会进行渲染操作。通过查阅资料，有的说是diff算法的原因，也有说是为了避免出现多个根元素，找不到以谁为主体。</p>
<p>​        这个现在主要作为一个了解。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=&quot;app&quot;&gt;1&lt;/div&gt;</span><br><span class="line">&lt;div id=&quot;app&quot;&gt;2&lt;/div&gt;</span><br></pre></td></tr></table></figure>



<h2 id="监听子组件事件"><a href="#监听子组件事件" class="headerlink" title="监听子组件事件"></a>监听子组件事件</h2><p>​        父组件可以给子组件传值了，但是子组件如何在一定的条件下通知父组件呢。</p>
<p>​        使用方式：</p>
<p>​        1.首先父元素在传递的时候，传递一个可以被子元素监听的方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;blog-post @test=&quot;enlarge&quot; post=&quot;&#123;title: 1&#125;&quot;&gt;&lt;/blog-post&gt;</span><br></pre></td></tr></table></figure>

<p>​        2.然后子元素就可以通过使用 $emit 进行调用这个方法。注意$emit(‘xxxx’)，xxx就是那个元素上的属性attribute，</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;button v-on:click=&quot;$emit(&#x27;test&#x27;)&quot;&gt;</span><br></pre></td></tr></table></figure>

<p>​        3.传递值的方式，这个方法的第一个是方法名，后面的就是要传递的值。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$emit(&#x27;test&#x27;, 1, 2);</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<ul>
<li><p>父元素进行传递时，直接写上方法名即可 <code>@test=&quot;enlarge&quot;</code> </p>
</li>
<li><p>因为html是不分大小写的，所以进行传递的时候，建议不要带有大写，对于$emit(‘xxx’)，存在大写，则会监听失败。</p>
</li>
<li><p>如果是 <code>@test=&quot;enlarge()&quot;</code> 那么子组件传递参数则无效，<code>$emit(&#39;test&#39;, 1, 2);</code> 子组件这个写法虽然传递了参数，但是并不会传递值，因为父组件在传递的时候是直接传递了方法的调用的结果。</p>
<ul>
<li>```<br>@test=”enlarge()<br>$emit(‘test’, 1, 2);结果：空<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">*  `@test=&quot;enlarge(1, 2)` 同理，这样在子组件调用的时候传递过来的值就直接是是1和2。并不会因为 `$emit(&#x27;test&#x27;, 321, 123);` 改成321，123。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    @test=&quot;enlarge(1, 2)</span><br><span class="line">    $emit(&#x27;test&#x27;, 11111, 22222);</span><br><span class="line">    </span><br><span class="line">    结果：1, 2</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p> <code>@test=&quot;enlarge($event, 12, 321, 312)&quot;</code> 这样写有是一个特点，你会发现，这个$event 代表的不是点击的事件了，而是子组件传递的值。这个event就类似于了一个子组件的待定参数。</p>
</li>
<li><p>```<br>@test=”enlarge($event, 1, 2)<br>$emit(‘test’, 11111, 22222);</p>
<p>结果：11111, 1, 2</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 使用事件抛出一个值</span><br><span class="line"></span><br><span class="line">​		可以使用 `$emit` 的第二个参数来提供这个值</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<button v-on:click="$emit('enlarge-text', 0.1)">
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		然后当在父级组件监听这个事件的时候，我们可以通过 `$event` 访问到被抛出的这个值</span><br><span class="line"></span><br></pre></td></tr></table></figure>
@enlarge-text="postFontSize += $event"
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		如果这个是一个方法，那么这个值会作为第一个参数传入这个方法</span><br><span class="line"></span><br></pre></td></tr></table></figure>
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 在组件上使用 v-model</span><br><span class="line"></span><br><span class="line">​		首先我们可以这样理解</span><br><span class="line"></span><br></pre></td></tr></table></figure>
</button><input v-model="searchText"></li>
</ul>
<p>等价于</p>
<p>&lt;input<br>  v-bind:value=”searchText”<br>  v-on:input=”searchText = $event.target.value”</p>
<blockquote>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		v-model的效果就是值的改变会影响到view的改变，输入的变化会影响值的改变。而v-bind，值的改变会影响到视图的改变，但是并没有双向的绑定。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">​		所以用在组件上时。</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>&lt;custom-input<br>  v-bind:value=”searchText”<br>  v-on:input=”searchText = $event”</p>
<blockquote>

</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		所以此时我们需要绑定一个input方法将其传递出来。</span><br><span class="line"></span><br><span class="line">​		为了让它正常工作，这个组件内的 `&lt;input&gt;` 必须：</span><br><span class="line"></span><br><span class="line">- 将其 `value` attribute 绑定到一个名叫 `value` 的 prop 上</span><br><span class="line">- 在其 `input` 事件被触发时，将新的值通过自定义的 `input` 事件抛出</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>Vue.component(‘custom-input’, {<br>  props: [‘value’],<br>  template: <code>     &lt;input       v-bind:value=&quot;value&quot;       v-on:input=&quot;$emit(&#39;input&#39;, $event.target.value)&quot;     &gt;</code><br>})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		所以此时我们就能理解了，上面的那个组件使用v-model时的传递方式了。</span><br><span class="line"></span><br><span class="line">​		同时我么可以看一下那个[自定义事件的 v-model](https://cn.vuejs.org/v2/guide/components-custom-events.html)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>Vue.component(‘base-checkbox’, {<br>  model: {<br>    prop: ‘checked’,<br>    event: ‘change’<br>  },<br>  props: {<br>    checked: Boolean<br>  },<br>  template: <code>     &lt;input       type=&quot;checkbox&quot;       v-bind:checked=&quot;checked&quot;       v-on:change=&quot;$emit(&#39;change&#39;, $event.target.checked)&quot;     &gt;</code><br>})</p>
<p>使用<br><base-checkbox v-model="lovingVue"></base-checkbox></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">​		这里的model里面有prop和event，其中checked代表了传递的值。这个名字可以自己定义。 这里的event，值为change，则代表了是change事件，如果命名为input则为input的事件，当然，其实这里也是可以自己命名的。主要是为了方便认知。</span><br><span class="line"></span><br><span class="line">​		这个和上一个组件的通信的区别</span><br><span class="line"></span><br><span class="line">* 普通的是将值返回给上级，然后上级进行方法的操作。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    &lt;c :name=&quot;name&quot; @inputf=&quot;fn&quot;&gt;12&lt;/c&gt;</span><br><span class="line">    </span><br><span class="line">    子组件的内容：</span><br><span class="line">    &lt;input type=&quot;text&quot; :value=&quot;name&quot; @input=&quot;this.$emit(&#x27;inputf&#x27;, event.target.value);&quot;&gt;</span><br><span class="line">    </span><br><span class="line">    这里再对fn写上一个方法，此时对于一个input输入就会出现对应的方法被执行。</span><br></pre></td></tr></table></figure>

<ul>
<li><p>对于v-model，则是发现直接将其传递给上级，上级不需要再指定一个方法。</p>
<ul>
<li><p>```<br><c v-model="searchText"></c></p>
<p>子组件的内容<br>&lt;input type=”text” :value=”myInput” @input=”inputE($event)”&gt;</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 首先在使用组件的时候，使用v-mdoel方法。子组件，此时可以使用 model对象进行指定。当然，如果此时不指定怎么办</span><br><span class="line"></span><br><span class="line">* 对于有value的情况：</span><br><span class="line"></span><br><span class="line">  * 首先，对于父组件使用v-model传递给了子组件的值，子组件如果使用了value的变量名，则会以此值进行接收。就算是checkbox，也是使用的value进行接收。不管子组件的内容(目前我的测试来说。)</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    props: &#123;</span><br><span class="line">      value: &#123;</span><br><span class="line">      	type: Boolean,</span><br><span class="line">      	defalut: false,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    记住props的写法，开始我写成了data式的写法，把默认值直接写在了后面，如果直接写后面是写变量的类型</span><br><span class="line">    props: &#123;</span><br><span class="line">    	value: String,</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></li>
<li><p>对于没有value的情况：</p>
<ul>
<li><p>没有value，还没有添加一个model对象进行指定，那么就不会传入成功。</p>
</li>
<li><p>进行了model的指定，那么便会使用这个变量进行赋值。</p>
<ul>
<li>```<br>model: {<br>  prop: ‘myInput’,<br>  event: ‘inp’<br>},<br>props: [‘myInput’],<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 到此，我们已经解决了如何传值，下一步就是更新数据。</span><br><span class="line"></span><br><span class="line">  * 因为 v-model的特点就是会将值进行了绑定，所以我们只需要通知同步就行了</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    &lt;input type=&quot;text&quot; :value=&quot;myInput&quot; @input=&quot;inputE($event)&quot;&gt;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>input事件，绑定了inputE方法，然后inputE里面通过$emit进行传递。事件名称就是model里面的事件名称，inp, 如果没有进行重命名，那么就是 input事件。父组件不需要做什么，因为v-model自动对事件和参数进行了赋值。当然，也是可以赋值常数的。</p>
</li>
</ul>
</li>
<li><p>同时我们通过这个案例也知道了，如果你对一个input输入框加了v-model，也加了input的监听，在input的监听修改了v-model的值，那么会以input的为主。</p>
</li>
</ul>
</li>
</ul>
<h2 id="通过插槽分发内容"><a href="#通过插槽分发内容" class="headerlink" title="通过插槽分发内容"></a>通过插槽分发内容</h2><p>​        简单来说，就是可以在标签内部使用标签，然后标签可以传递给子元素显示。父元素的使用方式就是下面这样。子元素只需要定义一个 slot，然后slot的位置就会显示为你定义的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;alert-box&gt;</span><br><span class="line">  Something bad happened.</span><br><span class="line">&lt;/alert-box&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Vue.component(&#x27;alert-box&#x27;, &#123;</span><br><span class="line">  template: `</span><br><span class="line">    &lt;div class=&quot;demo-alert-box&quot;&gt;</span><br><span class="line">      &lt;strong&gt;Error!&lt;/strong&gt;</span><br><span class="line">      &lt;slot&gt;&lt;/slot&gt; 这里就会被渲染为其他的。</span><br><span class="line">    &lt;/div&gt;`</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        这里在简单的说几个地方。</p>
<p>​        1.如果使用了多个slot，默认每个slot都会全部都会显示，但是又不是你想的那种显示。我不知道怎么描述。直接看例子就懂了：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;p&gt;123&lt;/p&gt;</span><br><span class="line">&lt;slot&gt;&lt;/slot&gt;</span><br><span class="line">&lt;slot&gt;&lt;/slot&gt;</span><br><span class="line">&lt;p&gt;321&lt;/p&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;tt&gt;</span><br><span class="line">  &lt;div&gt;123&lt;/div&gt;</span><br><span class="line">  &lt;div&gt;321&lt;/div&gt;</span><br><span class="line">&lt;/tt&gt;</span><br></pre></td></tr></table></figure>

<p>​        下面这个我定义了两个slot，然后组件名为tt，tt里面有两个div标签值为123和321。你可能会认为一个 slot为123，一个slot为321.但是其实不是，因为你没有给定name，所以这两个div会被当成一个传递给插槽。然后两个插槽都会被赋值。所以值为</p>
<img src="/.io//image-20211105095952701.png" alt="image-20211105095952701" style="zoom:50%;">



<p>​        那么要如何实现上面预想的效果呢，使用name。一个不带 <code>name</code> 的 <code>&lt;slot&gt;</code> 出口会带有隐含的名字“default”。</p>
<p>​        然后就是父组件如何使用了，这里有三个写法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;div slot=&quot;aa&quot;&gt;123&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">&lt;template v-slot:aa&gt;</span><br><span class="line">	&lt;div&gt;123&lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;template #aa&gt;</span><br><span class="line">	&lt;div&gt;123&lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br></pre></td></tr></table></figure>

<p>​        上面这三个写法，</p>
<ul>
<li><p>第一个是一个旧的写法，不建议，因为建议是使用一个template进行包裹，template作为一个html5的新特性。</p>
</li>
<li><p>第二个是使用的v-slot进行绑定。但是需要将其放在template上，才有效果</p>
</li>
<li><p>第三个就是第二个的一个语法糖写法。</p>
</li>
<li><p>然后就是如何使用变量，首先可以使用 v-bind 进行绑定。其次也可以使用 [] 进行表示。</p>
<ul>
<li>```<br>:slot=”name” :v-slot:name :#name<br>v-slot:[name] #[name]<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">​		然后就是插槽是会将值进行覆盖的。所以如果你在slot上写的一些样式和方法不会显示，对应的方式就是（**v-if，v-for** 有效果，因为这些是对DOM树进行了变化，所以会在DOM树的添加，而不是对一个属性的覆盖。但是对于一些class和v-show就没用了。）</span><br><span class="line"></span><br><span class="line">* 第一种，父元素写方法和样式，但是这样一个子组件就对父组件不透明了</span><br><span class="line"></span><br><span class="line">* 第二种，在外面套上一层标签。向下面这样就行了。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    &lt;div v-show=&quot;false&quot;&gt;</span><br><span class="line">    	&lt;slot&gt;&lt;/slot&gt;</span><br><span class="line">    &lt;/div&gt;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<p>​        其他的部分，详见Vue的 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/components-slots.html">插槽</a> 部分。</p>
<h2 id="动态组件"><a href="#动态组件" class="headerlink" title="动态组件"></a>动态组件</h2><p>​        简单来说就是不同组件会进行动态切换，所以可以使用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;component :is=&quot;name&quot;&gt;&lt;/component&gt;</span><br><span class="line">&lt;button @click=&quot;change&quot;&gt;change&lt;/button&gt;</span><br></pre></td></tr></table></figure>

<p>​        这里 component 是一个标签，is使用v-bind绑定了name，然后通过一个点击事件来修改了name的值，所以component，is就会被指定修改成其他的组件名。</p>
<p>​        这个is属性应该是html里面的那个is属性，但是具体的使用方式我现在看不懂，可以取MDN里面进行了解，这里我们就当作is会指定一个组件名，然后这个component标签就会被替换成组件名。</p>
<p>​        在上述示例中，name可以包括：</p>
<ul>
<li>已注册组件的名字，或</li>
<li>一个组件的选项对象</li>
</ul>
<p>注意：</p>
<p>​        这个is属性可以用于常规的html元素上。</p>
<p>​        但是对于attribute将会作为DOM attribute进行绑定，对于像 <code>value</code> 这样的 property，若想让其如预期般工作，你需要使用 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/api/#v-bind"><code>.prop</code> 修饰器</a>。</p>
<p>​        这里就扯出了 attribute 和 property 的一个区别，我这里就贴一个 <a target="_blank" rel="noopener" href="https://stackoverflow.com/questions/6003819/properties-and-attributes-in-html#answer-6004028">StackOverflow</a> 和 一个对应 StackOverflow 的 <a target="_blank" rel="noopener" href="https://blog.csdn.net/rudy_zhou/article/details/104058741">CSDN </a> 的一个中文的讲解 </p>
<p>​        大概就是说，attribute属性是一个HTML的上的属性，而property是一个DOM对象上的属性。有的属性开始是继承了attribute，但是后续会被修改，此时可以从property看出，但是不会从attribute看出。</p>
<h2 id="解析-DOM-模板时的注意事项"><a href="#解析-DOM-模板时的注意事项" class="headerlink" title="解析 DOM 模板时的注意事项"></a>解析 DOM 模板时的注意事项</h2><p>​        简单来说，就是有的HTML 元素限制了其内部的元素是哪些，对于不属于的，会被提升到外部，触发其他问题。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;ul&gt;、&lt;ol&gt;、&lt;table&gt; 和 &lt;select&gt;</span><br></pre></td></tr></table></figure>

<p>​        有的元素是，只能存在于特定的元素内部</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;li&gt;、&lt;tr&gt; 和 &lt;option&gt;</span><br></pre></td></tr></table></figure>

<p>​        案例</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;table&gt;</span><br><span class="line">  &lt;blog-post-row&gt;&lt;/blog-post-row&gt;</span><br><span class="line">&lt;/table&gt;</span><br></pre></td></tr></table></figure>

<p>​        对于上面的情况，blog-post-row 会被提升到外部，所以会出现页面布局的问题。</p>
<p>​        解决方式，使用is attribute。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;table&gt;</span><br><span class="line">  &lt;tr is=&quot;blog-post-row&quot;&gt;&lt;/tr&gt;</span><br><span class="line">&lt;/table&gt;</span><br></pre></td></tr></table></figure>



<p>需要注意的是<strong>如果我们从以下来源使用模板的话，这条限制是<em>不存在</em> 的</strong>：</p>
<ul>
<li><p>字符串 (例如：<code>template: &#39;...&#39;</code>) </p>
<ul>
<li><pre><code>Vue.component(&#39;tt&#39;, &#123;
  template: `
    &lt;table&gt;
        &lt;p&gt;1&lt;/p&gt;
    &lt;/table&gt;
  `,
&#125;);
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">  - 此时 p 标签存在于table 内部。</span><br><span class="line"></span><br><span class="line">- [单文件组件 (`.vue`)](https://cn.vuejs.org/v2/guide/single-file-components.html) </span><br><span class="line"></span><br><span class="line">- [`&lt;script type=&quot;text/x-template&quot;&gt;`](https://cn.vuejs.org/v2/guide/components-edge-cases.html#X-Template) </span><br><span class="line"></span><br><span class="line">  ​	当然这些，我也没有测试过，所以不清楚。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">至此，简单的一个基础就了解完了，详细的还是看看Vue官网的 文档和API吧</span><br><span class="line"></span><br></pre></td></tr></table></figure>
https://cn.vuejs.org/v2/api/
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>
https://cn.vuejs.org/v2/guide/
</code></pre>
</li>
</ul>
</li>
</ul>
</div>
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/29/JavaScript/%E9%9A%8F%E7%AC%94/JavaScript-%E5%86%92%E6%B3%A1%E5%92%8C%E6%8D%95%E8%8E%B7/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/29/JavaScript/%E9%9A%8F%E7%AC%94/JavaScript-%E5%86%92%E6%B3%A1%E5%92%8C%E6%8D%95%E8%8E%B7/" class="post-title-link" itemprop="url">JavaScript-冒泡和捕获</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-29 10:54:26" itemprop="dateCreated datePublished" datetime="2021-10-29T10:54:26+08:00">2021-10-29</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p> <strong>前言:</strong></p>
<h4 id="JavaScript-DOM的监听方式"><a href="#JavaScript-DOM的监听方式" class="headerlink" title="JavaScript-DOM的监听方式"></a><strong>JavaScript-DOM的监听方式</strong></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">dom.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">  console.log(&#x27;father1 捕获&#x27;);</span><br><span class="line">&#125;, true);</span><br><span class="line"></span><br><span class="line">dom.onclick = function (e) &#123;</span><br><span class="line">  console.log(&#x27;a2 冒泡&#x27;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在这里,又被称为 <strong>DOM0级</strong> 和 <strong>DOM2级</strong></p>
<p><strong>0级DOM</strong>:</p>
<ul>
<li>标签内部的 onclick 事件</li>
<li>JavaScript 的 onclick = function() {} 函数</li>
</ul>
<p><strong>2级DOM:</strong></p>
<ul>
<li>就是标准的事件模型</li>
<li><strong>addEventListener</strong> 和 <strong>removeEventListener</strong></li>
</ul>
<h1 id="JavaScript-冒泡和捕获"><a href="#JavaScript-冒泡和捕获" class="headerlink" title="JavaScript-冒泡和捕获"></a>JavaScript-冒泡和捕获</h1><p>参考文章，感觉写的很详细</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://blog.csdn.net/sinat_33523805/article/details/94018242</span><br></pre></td></tr></table></figure>

<p>​        在一个 <code>Event</code> 的事件中，存在三个阶段：<code>捕获，目标和冒泡</code></p>
<p><strong>三个阶段的顺序：</strong></p>
<ul>
<li><p>首先是从根节点出发，到达目标节点，若此过程中触发了事件，则被称为<strong>捕获阶段</strong></p>
</li>
<li><p>然后当节点到达定义点击事件的目标节点时，处于<strong>目标阶段</strong></p>
</li>
<li><p>在目标节点触发事件后，最后就会一路往上回到根节点，处于 <strong>冒泡阶段</strong></p>
<p>​    给一张对应的图片。</p>
</li>
</ul>
<img src="/.io//image-20210907141230550.png" alt="image-20210907141230550" style="zoom:67%;">

<p>​        如何在创建一个点击监听的时候，同时定义是处于冒泡还是捕获阶段。</p>
<p>​        通过一个 <code>addEventListener</code> 函数的参数，分别为 <strong>事件名， 回调函数， 在什么阶段执行</strong>。第三个参数就是判断是处于什么阶段的。<strong>true代表捕获阶段，false代表了冒泡阶段</strong>。</p>
<p>​        对于target，顺序不是按照捕获和冒泡的顺序，而是按照监听函数的创建顺序。</p>
<p>​        可以通过 <code>event.eventPhase</code> 的值来判断是处于哪个阶段。</p>
<p>​            <code>1，捕获阶段。2，目标阶段。3，冒泡阶段</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">father.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">  console.log(&#x27;father 捕获&#x27;);</span><br><span class="line">  console.log(e.eventPhase);	// 1</span><br><span class="line">&#125;, true);</span><br><span class="line">father.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">  console.log(&#x27;father 冒泡&#x27;);</span><br><span class="line">&#125;, false);</span><br><span class="line"></span><br><span class="line">children.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">  console.log(&#x27;children 冒泡&#x27;);</span><br><span class="line">&#125;, false);</span><br><span class="line">children.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">  console.log(&#x27;children 捕获&#x27;);</span><br><span class="line">&#125;, true);</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">father 捕获</span><br><span class="line">children 冒泡</span><br><span class="line">children 捕获</span><br><span class="line">father 冒泡</span><br></pre></td></tr></table></figure>



<p><strong>结论：</strong></p>
<ul>
<li><p>捕获是从根到target， 冒泡是从target到根。</p>
</li>
<li><p>先捕获，后冒泡。</p>
</li>
<li><p>可以通过 <code>addEventListener</code> 的第三个参数来决定这个监听处于捕获还是处于冒泡。默认是冒泡阶段。</p>
</li>
<li><p>对于 <code>target</code> 元素，没有捕获冒泡一说，先定义先执行。</p>
</li>
<li><p>可以通过 <code>event.eventPhase</code> 来判断当前处于什么阶段。</p>
</li>
</ul>
<h1 id="取消事件传递"><a href="#取消事件传递" class="headerlink" title="取消事件传递"></a>取消事件传递</h1><p>​        通过这三个方式 <code>stopPropagation()</code> 、<code>prenventDefault()</code>、<code>return false;</code>、<code>stopImmediatePropagation()</code>。</p>
<ul>
<li><p><code>stopPropagation()</code> </p>
<ul>
<li>会停止事件的传递。但是不会阻止事件的默认方法。</li>
</ul>
</li>
<li><p><code>stopImmediatIePropagation()</code> </p>
<ul>
<li>同上，但是对于多个相同的事件都会被阻止。具体区别一会儿看案例.</li>
</ul>
</li>
<li><p><code>prenventDefault()</code> </p>
<ul>
<li>取消掉元素的默认行为.</li>
</ul>
</li>
<li><p><code>return false;</code> </p>
<ul>
<li>会取消默认行为,但是只能用于 DOM0级.</li>
<li>但是不会终止事件的传递.</li>
</ul>
</li>
</ul>
<h2 id="stopPropagation-和-stopImmediatIePropagation-的使用"><a href="#stopPropagation-和-stopImmediatIePropagation-的使用" class="headerlink" title="stopPropagation 和 stopImmediatIePropagation 的使用"></a>stopPropagation 和 stopImmediatIePropagation 的使用</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">children1.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">	console.log(&#x27;a 捕获&#x27;);</span><br><span class="line">	e.stopPropagation();</span><br><span class="line">&#125;, true);	//为true,代表了捕获.</span><br><span class="line">  </span><br><span class="line">children1.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">    console.log(&#x27;a1 捕获&#x27;);</span><br><span class="line">&#125;, true);	//为true,代表了捕获.</span><br><span class="line"></span><br><span class="line">这里对上面进行了 stopPropagation 所以会停止传递,但是</span><br><span class="line">	对于上层元素,传递会直接停止,所以如果是在捕获层进行了使用,那么就会在调用了本层方法后,就会停止, 如果是在冒泡层进行使用,就会结束后续的冒泡行为.</span><br><span class="line">	对于 target 的使用,因为 target 不分冒泡和捕获,所以两个都会执行.</span><br><span class="line">执行结果:	father 捕获, target 捕获, target 冒泡(阻止了事件的继续.虽然这个阻止放在了 捕获 位置, 但是对于 target 是不分 冒泡 和 捕获 的.所以 target 的冒泡也会执行.)</span><br><span class="line">	其中对于 target 的捕获和冒泡的顺序,按照定义的顺序执行.</span><br><span class="line"></span><br><span class="line">对于 stopImmediatIePropagation 的使用,大体上和上面起始差不多,最大的区别就是,不但会停止传递,并且会停止本层的相同事件.</span><br><span class="line">比如代码类型:</span><br><span class="line"></span><br><span class="line">    children1.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">        console.log(&#x27;a 捕获&#x27;);</span><br><span class="line">    	e.stopImmediatePropagation();</span><br><span class="line">    &#125;, true);</span><br><span class="line">    children1.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">        console.log(&#x27;a1 捕获&#x27;);</span><br><span class="line">    &#125;, true);</span><br><span class="line">    children1.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">        console.log(&#x27;a 冒泡&#x27;);</span><br><span class="line">    &#125;, false);</span><br><span class="line">	</span><br><span class="line">	我这里定义了两个相同的捕获. 但是使用的是 e.stopImmediatePropagation(); 所以,对于相同的事件都会停止,然后因为这个 stopImmediatePropagation 放在了最上面定义的位置,所以放在下面的都不会执行. 如果我把这个函数的位置放在了第二个,那么第一个还是会执行</span><br><span class="line">执行结果:</span><br><span class="line">	father 捕获, target 捕获(阻止了事件的传递. 并且因为target的捕获和冒泡属于同一类型,所以都被阻止了.)</span><br></pre></td></tr></table></figure>

<p><strong>简单总结:</strong></p>
<ul>
<li><strong>stopPropagation</strong><ul>
<li>对于非target, 会阻止后续的事件, 但是对于相同的事件不会阻止.</li>
<li>对于 target, 因为 target 是<strong>不分冒泡和捕获</strong>,所以只会阻止上级元素的事件,对于 target 的<strong>冒泡</strong> 和 <strong>捕获</strong> 都不会阻止.</li>
</ul>
</li>
<li><strong>stopImmediatIePropagation</strong><ul>
<li>这个不但会阻止后续的事件, 对于相同的事件也会阻止.</li>
</ul>
</li>
<li><strong>相同点</strong>是: 他们都<strong>不会阻止元素的默认事件的执行,就算是捕获和冒泡没有到target.</strong></li>
</ul>
<h2 id="prenventDefault-使用"><a href="#prenventDefault-使用" class="headerlink" title="prenventDefault 使用"></a>prenventDefault 使用</h2><p><strong>作用:</strong></p>
<p>​    取消元素的默认行为.如果放在了父元素,那么子元素的所有默认行为都会被取消.</p>
<p><strong>使用方式:</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">  children1.addEventListener(&#x27;click&#x27;, function (e) &#123;</span><br><span class="line">    console.log(&#x27;a 捕获&#x27;);</span><br><span class="line">    e.preventDefault();</span><br><span class="line">  &#125;, true);</span><br><span class="line">  </span><br><span class="line">这个很简单.</span><br></pre></td></tr></table></figure>



<h2 id="return-false-的使用"><a href="#return-false-的使用" class="headerlink" title="return false; 的使用"></a>return false; 的使用</h2><p>这个的使用方式不和上面的一样.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">  children1.onclick = function (e) &#123;</span><br><span class="line">    console.log(&#x27;a2 冒泡&#x27;);</span><br><span class="line">    return false;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">不能在 addEventListener 的回调函数里面使用. 因为这个是通过return 的值为false,来进行的定义,如果要使用 addEventListener 的回调的话, 函数的返回值不能正确返回,但是要怎么实现我也不知道.</span><br></pre></td></tr></table></figure>



<h1 id="事件委托"><a href="#事件委托" class="headerlink" title="事件委托"></a>事件委托</h1><p>​        理解很简单, 就是子元素的点击, 父级也可以进行捕获和冒泡, 很多人说事件委托是利用的冒泡原理, 但是通过前面的学习我们可以知道,事件委托,无非就是 子元素 的点击可以被父元素所监听到. 所以这里肯定会感觉不对, 然后我去网上看了一篇文章,  然后断章取义了一番.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://blog.csdn.net/mmrsdym/article/details/39209375</span><br></pre></td></tr></table></figure>

<p>​        我了解到了,为什么事件委托要使用的是冒泡原理, 而不是使用的捕获的原因.</p>
<p>​        大概的意思就是, 一个元素是先进行的捕获行为, 然后再进行的冒泡行为. 所以如果我们将事件委托放在了, 捕获上面. 如果要阻止事件的行为, 那么就会让子元素的所有事件都不能执行, 而放在了事件的冒泡的话, 子元素的一些行为还是可以执行的.  所以这就是为什么事件委托需要放在冒泡的原因. </p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/27/%E6%B5%8F%E8%A7%88%E5%99%A8/sass%E9%A2%84%E5%A4%84%E7%90%86/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/27/%E6%B5%8F%E8%A7%88%E5%99%A8/sass%E9%A2%84%E5%A4%84%E7%90%86/" class="post-title-link" itemprop="url">sass预处理</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-27 16:05:34" itemprop="dateCreated datePublished" datetime="2021-10-27T16:05:34+08:00">2021-10-27</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/css/" itemprop="url" rel="index"><span itemprop="name">css</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/css/sass/" itemprop="url" rel="index"><span itemprop="name">sass</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="安装sass"><a href="#安装sass" class="headerlink" title="安装sass"></a>安装sass</h1><p>使用sass，需要安装ruby，然后再安装sass</p>
<p>如果是webpack这种项目的，可以使用 npm 下载包</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&quot;sass&quot;: &quot;^1.49.0&quot;,</span><br><span class="line">&quot;sass-loader&quot;: &quot;^7.1.0&quot;,</span><br><span class="line">上面这两个下载了就可以编译了</span><br><span class="line"></span><br><span class="line">还有一个是 node-sass，但是这个下载好像需要python环境，而且貌似不需要也可以使用？但是对于这个sass的安装和环境的一些我还是不算很是理解清楚。</span><br></pre></td></tr></table></figure>



<h2 id="第一步，安装-ruby"><a href="#第一步，安装-ruby" class="headerlink" title="第一步，安装 ruby"></a>第一步，安装 ruby</h2><p>首先，我们得知道，Sass是基于Ruby开发的，所以要运行Sass都需要一个Ruby环境.</p>
<p>所以下面这个链接就是 ruby 的下载链接，如果下载速度慢，可以使用 迅雷来增加下载速度。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://www.ruby-lang.org/en/downloads/</span><br></pre></td></tr></table></figure>

<p>阿里云盘的链接， 阿里云盘应该挺快.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">「rubyinstaller-devkit-2.7.5-1-x64.exe」https://www.aliyundrive.com/s/RXSr5Fh38uz</span><br><span class="line">点击链接保存，或者复制本段内容，打开「阿里云盘」APP ，无需下载极速在线查看，视频原画倍速播放。</span><br></pre></td></tr></table></figure>



<p>然后就是安装了</p>
<p>这里也直接给别人的安装链接</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://www.cnblogs.com/padding1015/p/7133811.html</span><br></pre></td></tr></table></figure>

<p><strong>我就提几个重点</strong></p>
<ul>
<li><p>要添加到 Path，这样可以直接在cmd里面进行运行。</p>
</li>
<li><p>在最后一步之前 finish  <strong>ridk install</strong>  这个去掉，因为没有使用镜像，会比较慢，要引入镜像</p>
<ul>
<li><p>参考链接</p>
</li>
<li><p>```<br><a target="_blank" rel="noopener" href="https://blog.csdn.net/mscf/article/details/82627951">https://blog.csdn.net/mscf/article/details/82627951</a></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">  * 然后也就是 添加镜像，设置 gem 源了</span><br><span class="line"></span><br><span class="line">* 我这里记录链接里面的重点，怕到时候链接没了</span><br><span class="line"></span><br><span class="line">* ```</span><br><span class="line">  双击开始安装，选择全部安装；</span><br><span class="line">  在安装结束时，去除ridk install的选项，因为从默认的原去下载几百兆会非常缓慢；</span><br><span class="line">  查找Ruby安装目录下的msys64\etc\pacman.d，编辑更新源：</span><br><span class="line">  </span><br><span class="line">  Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686 加入mirrorlist.mingw32首位</span><br><span class="line">  Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64 加入mirrorlist.mingw64首位</span><br><span class="line">  Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch 加入mirrorlist.msys首位</span><br><span class="line">  </span><br><span class="line">  执行在命令行执行ridk install（如果安装时选择了不加入系统环境变量的，去Ruby安装目录的bin之下执行），一路回车至结束；</span><br><span class="line">  更新gem源：</span><br><span class="line">  gem sources --add https://mirrors.tuna.tsinghua.edu.cn/rubygems/ --remove https://rubygems.org/</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<h2 id="然后就是安装sass"><a href="#然后就是安装sass" class="headerlink" title="然后就是安装sass"></a>然后就是安装sass</h2><p>先 <strong>gem env</strong> 了解一下安装了路径</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">参考资料：</span><br><span class="line">https://qastack.cn/programming/19072070/how-to-find-where-gem-files-are-installed</span><br><span class="line"></span><br><span class="line">https://guides.rubygems.org/command-reference/#gem_environment</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">注意： INSTALLATION DIRECTORY</span><br><span class="line">			GEM PATHS</span><br></pre></td></tr></table></figure>



<p>一波团灭</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">gem install sass</span><br><span class="line"></span><br><span class="line">然后准备回车就行了</span><br></pre></td></tr></table></figure>

<p>可能要等一会儿，我开始等了一会儿，没有反应，不知道是不是连接镜像查找的时候太久了。</p>
<p>不出意外是可以成功的，因为国内镜像我们在上一个blog上面设置好了的</p>
<h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><p>这个，一般搜一下怎么配置就行了</p>
<p>我的是 webstorm，所以好像当时自动配好了</p>
<h1 id="使用-sass"><a href="#使用-sass" class="headerlink" title="使用 sass"></a>使用 sass</h1><h2 id="嵌套选择"><a href="#嵌套选择" class="headerlink" title="嵌套选择"></a>嵌套选择</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">.aaa &#123;</span><br><span class="line">  xxx</span><br><span class="line">  </span><br><span class="line">  .bbb &#123;</span><br><span class="line">  	zzz</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>上面代码就是嵌套选择，就是代表下面的意思</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">.aaa &#123;</span><br><span class="line">	xxx</span><br><span class="line">&#125;</span><br><span class="line">.aaa .bbb &#123;</span><br><span class="line">	zzz</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="定义变量"><a href="#定义变量" class="headerlink" title="定义变量"></a>定义变量</h2><p>可以定义变量，然后进行使用，所以对于相同属性的，可以直接使用变量，后续的修改也只需要修改一个就行。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$padding-sm: 5px;</span><br><span class="line"></span><br><span class="line">.a &#123;</span><br><span class="line">	padding: $padding-sm;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">同时 scss 支持在定义变量的时候使用 !default,来进行替换</span><br><span class="line">	简单来说就是，如果定义的变量在之前已经定义过了。那么便不会重新赋值。如果是第一次的，那么便会重新赋值。</span><br></pre></td></tr></table></figure>



<h2 id="scss使用父元素-amp"><a href="#scss使用父元素-amp" class="headerlink" title="scss使用父元素 &amp;"></a>scss使用父元素 &amp;</h2><p>​        scss  通过使用 &amp; 来代表了父元素</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.box &#123;</span><br><span class="line">	&amp;:focus &#123; &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">.box:focus &#123; &#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.box &#123;</span><br><span class="line">	&amp;-d &#123; &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">.box-d &#123; &#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.box h1 &#123;</span><br><span class="line">	#b &amp; &#123; &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">#b .box h1 &#123; &#125;</span><br></pre></td></tr></table></figure>

<p>​        并且如果使用了 &amp;，那么，解析会有不同</p>
<ul>
<li>正常的解析</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.box &#123;</span><br><span class="line">	a &#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">.box a &#123;&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>使用了 &amp; 的解析，并不会变成查找 box 的内部，而是直接组成一个整体。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.box &#123;</span><br><span class="line">	&amp;-div &#123; &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">.box-div &#123; &#125;</span><br></pre></td></tr></table></figure>



<h2 id="混入-mixin"><a href="#混入-mixin" class="headerlink" title="混入 mixin"></a>混入 mixin</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">@mixin aa &#123;</span><br><span class="line">	@content</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@include aa() &#123;</span><br><span class="line">	color: red;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        并且混入可以携带参数。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/27/CSS/CSS-flex/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/27/CSS/CSS-flex/" class="post-title-link" itemprop="url">CSS-flex</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-27 15:54:35" itemprop="dateCreated datePublished" datetime="2021-10-27T15:54:35+08:00">2021-10-27</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/CSS/" itemprop="url" rel="index"><span itemprop="name">CSS</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="CSS-flex布局"><a href="#CSS-flex布局" class="headerlink" title="CSS-flex布局"></a>CSS-flex布局</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox</span><br></pre></td></tr></table></figure>

<p>​        flex就是弹性布局。</p>
<p>​        基本使用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">display: flex;</span><br></pre></td></tr></table></figure>



<h2 id="主轴"><a href="#主轴" class="headerlink" title="主轴"></a>主轴</h2><p>​        <code>flex-direction</code> 定义主轴</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">row，row-reverse</span><br><span class="line">代表inline，横向延申</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">column，column-reverse</span><br><span class="line">代表black，竖向排列</span><br></pre></td></tr></table></figure>

<p>​        其中 <code>reverse </code>代表翻转，就是反过来的排列顺序</p>
<h2 id="交叉轴，副轴"><a href="#交叉轴，副轴" class="headerlink" title="交叉轴，副轴"></a>交叉轴，副轴</h2><p>​        就是和主轴垂直的轴</p>
<p>​        如果主轴是横轴，那么交叉轴就是数轴。</p>
<h1 id="当使用了-Flex容器"><a href="#当使用了-Flex容器" class="headerlink" title="当使用了 Flex容器"></a>当使用了 Flex容器</h1><p>​        在定义了 <code>display: flex;</code> 之后的一些默认行为</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">元素排列一行，(因为 flex-direction 的默认值是 row )</span><br><span class="line">从主轴的起始线开始，这里起始线一般就是如果是row，代表了从左向右，其他的	情况查看MDN文档</span><br><span class="line">元素不会再主维度拉伸，但是可以缩小</span><br><span class="line">元素被拉伸来填充交叉轴大小</span><br><span class="line">flex-basis 为 auto</span><br><span class="line">flex-wrap 为 nowrap</span><br></pre></td></tr></table></figure>



<h1 id="对于flex属性值的行为"><a href="#对于flex属性值的行为" class="headerlink" title="对于flex属性值的行为"></a>对于flex属性值的行为</h1><h2 id="flex-direction-设置主轴"><a href="#flex-direction-设置主轴" class="headerlink" title="flex-direction 设置主轴"></a>flex-direction 设置主轴</h2><p>​        对定义了 <code>display: flex;</code> 的元素使用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">flex-direction</span><br><span class="line">	row</span><br><span class="line">		横向，从左到右</span><br><span class="line">	row-reverse</span><br><span class="line">		横向，从右到左</span><br><span class="line">		对于行内块元素和话，宽度的计算是和 Colum-reverse 类似的。</span><br><span class="line">	column</span><br><span class="line">		纵向，从上到下</span><br><span class="line">	column-reverse</span><br><span class="line">		纵向，从下到上</span><br><span class="line">		对于没有设置高度的，就会按照最小高度进行计算，(意思就是说，高度和column的一样，只是方向反了而已。)</span><br></pre></td></tr></table></figure>



<h2 id="flex-wrap-实现多行flex"><a href="#flex-wrap-实现多行flex" class="headerlink" title="flex-wrap 实现多行flex"></a>flex-wrap 实现多行flex</h2><p>​        对定义了 <code>display: flex;</code> 的元素使用</p>
<p>​        在这样做的时候，您应该把每一行看作一个新的<code>flex</code>容器。 任何空间分布都将在该行上发生，而不影响该空间分布的其他行。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">wrap</span><br><span class="line">	会换行，而不是进行缩小</span><br><span class="line">nowrap</span><br><span class="line">	不会换行，会使用缩小的规则进行缩小，对于不能缩小的，会导致溢出。</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<ul>
<li>如果在使用 wrap 时，使用了 flex:1， 时，这个时候就需要注意要不要定义 flex-basis 了。</li>
</ul>
<p>​            <strong>原因</strong>： 因为 <code>flex: 1</code>; 对应了 <code>flex-grow: 1</code> &amp; <code>flex-shrink: 1</code> &amp;&amp; <code>flex-basis: 0</code>  ，所以其实原因就是 flex-basis 为 0 了。所以如果不自己定义一个 flex-basis 的话，就不会进行换行。</p>
<ul>
<li><p>还有就是，对于每一个换行之后的元素，每一行都算是一个弹性行，所以对于以下代码</p>
<ul>
<li>```<br>flex: 1 1 160px;子元素在160px，换行之后，会对每一行的每个元素进行 扩张 和 收缩 的重新计算。<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* ```</span><br><span class="line">  参考 MDN 链接：</span><br><span class="line">  https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Mastering_Wrapping_of_Flex_Items</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<h2 id="简写属性-flex-flow"><a href="#简写属性-flex-flow" class="headerlink" title="简写属性 flex-flow"></a>简写属性 flex-flow</h2><p>​        对定义了 <code>display: flex;</code> 的元素使用</p>
<p>​        是 <code>flex-direction</code> 和 <code>flex-wrap</code> 的组合</p>
<p>​        对于没有写的，就会使用默认值：row 和 nowrap</p>
<p><strong>注：</strong></p>
<ul>
<li>从谷歌浏览器的显示来说:<ul>
<li>如果设置 <code>flex-flow: column; </code>  ，就直接代表了 <code>flex-direction: column;</code> ，而不会定义 <code>flex-wrap</code></li>
<li>如果设置 <code>flex-flow: wrap; </code>  ，就代表了 <code>flex-direction: initial;</code> 而  <code>flex-flow: wrap; </code> </li>
</ul>
</li>
</ul>
<h2 id="flex-basis-元素的空间大小"><a href="#flex-basis-元素的空间大小" class="headerlink" title="flex-basis 元素的空间大小"></a>flex-basis 元素的空间大小</h2><p>​        该属性的默认值是 <code>auto</code> ，此时，浏览器会检查这个元素是否具有确定的尺寸(width / heght ，这个看是使用 row 还是 Colum)，如果<strong>具有确定的尺寸</strong>，就会将该值设置为 flex-basis。如果没有设定尺寸，就会采用<strong>元素内容的尺寸</strong>。如果不使用  <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/box-sizing"><code>box-sizing</code></a> 改变盒模型的话，那么这个属性就决定了 flex 元素的内容盒（content-box）的尺寸。</p>
<h2 id="flex-grow-延展比例"><a href="#flex-grow-延展比例" class="headerlink" title="flex-grow 延展比例"></a>flex-grow 延展比例</h2><p>​        负值无效，默认为0</p>
<p>​        简单来说，这个是一个比例，对于存在可用空间的(可用空间：就是指在使用之后，父元素还存在剩余的空间。)， 子元素会根据这个比例将可用空间占据。</p>
<p>​        比如：两个子元素，一个为 1， 一个为 2，父元素的可用空间为 90，那么第一个就会扩张 1/(1+2) * 90 ， 第二个就会扩张 2/(1+2) * 90 。</p>
<h2 id="flex-shrink-收缩比例"><a href="#flex-shrink-收缩比例" class="headerlink" title="flex-shrink 收缩比例"></a>flex-shrink 收缩比例</h2><p>​        负值无效，默认为1</p>
<p>​        简单来说，就会对于如果容器不够排列 flex元素的空间。那么就会按照比例进行收缩。默认为1</p>
<p>​        计算方式： 这里的计算方式略和 <code>flex-grow</code> 有所不同。他的计算会和 <code>flex-basis</code> 相关联。这里给出计算的方法</p>
<p>​            每个元素的 <code>flex-basis</code> * <code>flex-shrink</code> 这个值作为一个比例<strong>X1</strong>，将所有参与计算的元素进行计算 <strong>X1~Xi 的求和 Xs</strong> ，然后再计算出超出的量，这个超出的量是 <strong>overflow = 子元素的flex-basis 的总和 - 父元素的宽度</strong>， 然后就是进行计算 <strong>Xi / Xs * overflow</strong>， 这个计算出的值就是需要减去的量，这里可能有点抽象，我们也给一个例子方便理解</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">div	width:600px</span><br><span class="line">	div flex: 1 1 200px;</span><br><span class="line">	div flex: 1 1 200px;</span><br><span class="line">	div flex: 1 2 300px;</span><br><span class="line"></span><br><span class="line">首先我们可以看出，这个是超出了，所以需要收缩，</span><br><span class="line">超出的量 overflow = 600 - 200 - 200 - 300 = 100px</span><br><span class="line">然后比例的计算</span><br><span class="line">	X1 = 1 * 200 = 200px</span><br><span class="line">	X2 = 1 * 200 = 200px</span><br><span class="line">	X3 = 2 * 300 = 600px</span><br><span class="line">所以 Xs = X1 + X2 + X3 = 1000px</span><br><span class="line">然后就是计算收缩的值	Xi / Xs * overflow</span><br><span class="line">	200 / 1000 * 100 = 20</span><br><span class="line">	200 / 1000 * 100 = 20</span><br><span class="line">	600 / 1000 * 100 = 60</span><br><span class="line">	</span><br><span class="line">所以最终的宽度是</span><br><span class="line">div width: 600px</span><br><span class="line">	div width: 180px</span><br><span class="line">	div width: 180px</span><br><span class="line">	div width: 240px</span><br></pre></td></tr></table></figure>

<p>在这里我也看到了一个更详细的一些计算教程，虽然里面的内容是否正确我没有进行参考，但是写的很详细，我就把链接贴出来</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://www.cnblogs.com/liyan-web/p/11217330.html</span><br></pre></td></tr></table></figure>

<p>​    <strong>注意点：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax</span><br></pre></td></tr></table></figure>

<p>​        这个元素在缩小的时候，不会小于最小宽度，至于这个最小宽度定义，我现在认为就是可以造成溢出的情况。举个例子：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">div</span><br><span class="line">	222222222222222222222222222222222222</span><br><span class="line">	</span><br><span class="line">	在这个情况，如果这个div想对于父元素的弹性布局，造成了溢出，但是因为最小的宽度为这个文字的一个长度，不会换行，所以会造成溢出。</span><br><span class="line">	而 22222 222222 222222222 222222 2222，这里，因为在 文字里面加入了空格，在html文档里面一个最小宽度是一个空格隔开的一个距离，所以会出现换行而不会让宽度溢出的情况。</span><br><span class="line">	这里记录一下会统计最小宽度的情况。</span><br><span class="line">		&#x27; &#x27;(不能使用 &amp;nbsp; ), &#x27;。&#x27;(。会在上一行), &#x27;，&#x27;(中文，号)，这里的原因应该是中文的。和， 里面的一个字符形势和 . ,不一样。</span><br><span class="line">	注意：只能是 英文和数字，中文会自动换行。原因应该是 对于英文，如果不打空格，浏览器会认为是一个单词，所以不会换行。</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<ul>
<li><code>flex-grow</code> &amp;&amp; <code>flex-shrink</code> 的值要为正数。</li>
</ul>
<h2 id="简写属性-flex"><a href="#简写属性-flex" class="headerlink" title="简写属性 flex"></a>简写属性 flex</h2><p>​        对弹性布局的子元素使用。</p>
<p>​        包含了： <code>flex-grow</code>  、 <code>flex-shrink</code> 和 <code>flex-basis</code> </p>
<p>​        对于每个属性的值，都有理解了。我们就说几个简写的代表意思</p>
<ul>
<li><code>flex: initial</code><ul>
<li>代表初始值：<code>flex: 0 1 auto</code></li>
</ul>
</li>
<li><code>flex: auto</code><ul>
<li>代表 <code>flex: 1 1 auto</code></li>
</ul>
</li>
<li><code>flex: none</code><ul>
<li>代表 <code>flex: 0 0 auto</code></li>
</ul>
</li>
<li><code>flex: &lt;positive-number&gt;</code><ul>
<li>代表 <code>flex: x x 0</code></li>
</ul>
</li>
</ul>
<h2 id="align-items-交叉轴方向对齐"><a href="#align-items-交叉轴方向对齐" class="headerlink" title="align-items 交叉轴方向对齐"></a>align-items 交叉轴方向对齐</h2><p>​        默认为 <code>stretch </code>，默认会被拉伸到最高元素的高度。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">stretch</span><br><span class="line">	拉伸到最高元素的高度</span><br><span class="line">flex-start</span><br><span class="line">	按flex容器的顶部对齐</span><br><span class="line">flex-end</span><br><span class="line">	按flex容器的下部对齐</span><br><span class="line">center</span><br><span class="line">	使它们居中对齐</span><br></pre></td></tr></table></figure>



<h2 id="justify-content-主轴方向对齐"><a href="#justify-content-主轴方向对齐" class="headerlink" title="justify-content 主轴方向对齐"></a>justify-content 主轴方向对齐</h2><p>​        初始值是 <code>flex-start</code>， 元素从容器的起始线排列。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">stretch</span><br><span class="line">	不了解</span><br><span class="line">flex-start</span><br><span class="line">	从容器的起始线排列</span><br><span class="line">flex-end</span><br><span class="line">	从容器的终止线开始排列</span><br><span class="line">center</span><br><span class="line">	在中间排列</span><br><span class="line">space-around</span><br><span class="line">	把元素排列好之后的剩余空间拿出来，平均分配到元素之间，所以元素之间间隔相等</span><br><span class="line">space-between</span><br><span class="line">	使每个元素的左右空间相等</span><br></pre></td></tr></table></figure>



<h1 id="对于flex的溢出："><a href="#对于flex的溢出：" class="headerlink" title="对于flex的溢出："></a>对于flex的溢出：</h1><h3 id="方式一"><a href="#方式一" class="headerlink" title="方式一"></a>方式一</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">对一个元素设置了flex布局，其中的子元素的子元素的宽度可以造成溢出</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">div.father</span><br><span class="line">	div.children</span><br><span class="line">	</span><br><span class="line">father 元素设置了弹性布局， children 元素只设置一个宽度，会发现 children 的宽度不会高于father的宽度。主要是因为涉及了</span><br></pre></td></tr></table></figure>

<img src="/.io//image-20211027210947232.png" alt="image-20211027210947232" style="zoom: 50%;">



<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">但是</span><br><span class="line">div.father</span><br><span class="line">	div.children</span><br><span class="line">		div.cChildren</span><br><span class="line"></span><br><span class="line">这个对于 cChildren 的宽度就会将 children 的宽度顶出来，造成溢出。</span><br><span class="line">其中，这里的宽度，如果 cChildren 大于了 father 就会将 cChildren 和 children 顶出来。</span><br><span class="line">但是如果 cChildren 大于了 children 的话，就会再 children 到达他所定义的宽度之后，就不会继续扩张了。</span><br></pre></td></tr></table></figure>

<img src="/.io//image-20211027211015004.png" alt="image-20211027211015004" style="zoom:50%;">



<img src="/.io//image-20211027212431340.png" alt="image-20211027211015004" style="zoom:50%;">



<p>​        但是这里的计算方式我没有理解到为什么。</p>
<h3 id="方式二"><a href="#方式二" class="headerlink" title="方式二"></a>方式二</h3><p>​        设置 <code>flex-shrink: 0;</code> 属性，因为设置了0之后代表了不会对超过的部分进行处理。</p>
<h3 id="方式三"><a href="#方式三" class="headerlink" title="方式三"></a>方式三</h3><p>​        这个是文字超出导致的溢出，就是如果文字，或者 img图片的设置超过了宽高也会造成溢出。</p>
<p>​        这个的原因是因为，对于英文和数字，浏览器不能识别你的单词是否是一个，所以如果你输入一串英文和数字，中间没有分割(前面有说)，就会造成溢出，而汉字不行。</p>
<img src="/.io//image-20211027213217557.png" alt="image-20211027213217557" style="zoom:50%;">



<h3 id="方式四"><a href="#方式四" class="headerlink" title="方式四"></a>方式四</h3><p>​        我们可以发现，flex 对于溢出的处理，默认只是针对于主轴，所以对于侧轴是没有溢出处理的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">.father &#123;</span><br><span class="line">    display: flex;</span><br><span class="line">    flex-direction: column;</span><br><span class="line">    width: 50px;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">.children &#123;</span><br><span class="line">	width: 60px;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<img src="/.io//image-20211027214029980.png" alt="image-20211027214029980" style="zoom:50%;">




      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/25/CSS/CSS-%E5%85%83%E7%B4%A0%E9%80%89%E6%8B%A9%E5%99%A8/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/25/CSS/CSS-%E5%85%83%E7%B4%A0%E9%80%89%E6%8B%A9%E5%99%A8/" class="post-title-link" itemprop="url">CSS-元素选择器</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-25 19:51:58" itemprop="dateCreated datePublished" datetime="2021-10-25T19:51:58+08:00">2021-10-25</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/CSS/" itemprop="url" rel="index"><span itemprop="name">CSS</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="CSS-元素选择器"><a href="#CSS-元素选择器" class="headerlink" title="CSS-元素选择器"></a>CSS-元素选择器</h1><h2 id="相邻兄弟选择器"><a href="#相邻兄弟选择器" class="headerlink" title="相邻兄弟选择器"></a>相邻兄弟选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Adjacent_sibling_combinator</span><br></pre></td></tr></table></figure>

<p>​        <strong>相邻兄弟选择器</strong> (<code>+</code>) 介于两个选择器之间，当第二个元素<em>紧跟在</em>第一个元素之后，并且两个元素都是属于同一个父<code>元素</code>的子元素，则第二个元素将被选中。</p>
<p><strong>注：</strong></p>
<p>​    第一，要相邻之后的，不相邻的，在前面的不管。 </p>
<p>​    只会选择一个，就算第二个元素有多个满足，只会选择最开始的一个。</p>
<p>​    但是对于第一个元素就可以有很多个。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">.f + .b &#123;</span><br><span class="line">	...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="属性选择器"><a href="#属性选择器" class="headerlink" title="属性选择器"></a>属性选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors</span><br></pre></td></tr></table></figure>

<p>​        CSS <strong>属性选择器</strong>通过已经存在的属性名或属性值匹配元素。</p>
<p>选择存在这个属性的元素，这个属性不一定要含有意义，也不一定有值</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">div[cc] &#123;</span><br><span class="line">	...</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">存在cc，但是cc是一个没有意义的属性，也可以被选中。</span><br><span class="line">&lt;div class=&quot;b&quot; cc&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>



<h3 id="属性选择器值的匹配"><a href="#属性选择器值的匹配" class="headerlink" title="属性选择器值的匹配"></a>属性选择器值的匹配</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">存在属性cc，并且值为xxx</span><br><span class="line">[cc=&#x27;xxx&#x27;]</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;b&quot; cc=&quot;xxx&quot;&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">存在属性cc，并且值包含了xx</span><br><span class="line">cc *= &#x27;xx&#x27;</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;b&quot; cc=&quot;111xxasf&quot;&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">存在属性cc，并且该属性是一个以空格作为分隔的值列表，其中至少有一个值为 xx。</span><br><span class="line">cc ~= &#x27;xx&#x27;</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;b&quot; cc=&quot;111 xx asf&quot;&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">存在属性cc，并且属性值为“xx”或是以“xx-”为前缀</span><br><span class="line">cc |= &#x27;xx&#x27;</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;b&quot; cc=&quot;xx-asf&quot;&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">存在属性cc，并且属性值是以 xx 开头的元素。</span><br><span class="line">cc ^= &#x27;xx&#x27;</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;b&quot; cc=&quot;xxasf&quot;&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">存在属性cc，并且属性值是以 xx 结尾的元素。</span><br><span class="line">cc $= &#x27;xx&#x27;</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;b&quot; cc=&quot;awwxx&quot;&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">存在属性cc，并且属性值是以 xx 结尾的元素。</span><br><span class="line">cc $= &#x27;xx&#x27;</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;b&quot; cc=&quot;awwxx&quot;&gt;1&lt;/div&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">在属性选择器右方括号前加 i用空格隔开，表示忽略大小写</span><br><span class="line">[cc $= &#x27;xx&#x27; i]</span><br><span class="line"></span><br><span class="line">div[cc $= &#x27;xx&#x27; i] &#123;</span><br><span class="line">	...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">同上，使用 s，表示区分大小写</span><br></pre></td></tr></table></figure>



<h2 id="子选择器"><a href="#子选择器" class="headerlink" title="子选择器"></a>子选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Child_combinator</span><br></pre></td></tr></table></figure>

<p>​        当使用  <code>&gt;</code> 选择符分隔两个元素时,它只会匹配那些作为第一个元素的**直接后代(**子元素)的第二元素. </p>
<p><strong>重点是 直接后代，而不是孙子代</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ele1 &gt; ele2 &#123;</span><br><span class="line">	...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="类选择器"><a href="#类选择器" class="headerlink" title="类选择器"></a>类选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Class_selectors</span><br></pre></td></tr></table></figure>

<p>​        在一个HTML文档中，CSS类选择器会根据元素的类属性中的内容匹配元素。类属性被定义为一个以空格分隔的列表项，在这组类名中，必须有一项与类选择器中的类名完全匹配，此条样式声明才会生效。</p>
<p>​    简单来说，就是class的属性，值是以空格进行的分割，需要其中一个值满足类选择器的属性值，才能有作用。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">.class &#123; ... &#125;</span><br><span class="line"></span><br><span class="line">他和属性选择器的具有相同的作用。</span><br><span class="line">[class ~= &#x27;class&#x27;] &#123; ... &#125;</span><br></pre></td></tr></table></figure>



<h2 id="后代选择器"><a href="#后代选择器" class="headerlink" title="后代选择器"></a>后代选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Descendant_combinator</span><br></pre></td></tr></table></figure>

<p>​        <strong>后代组合器</strong>（通常用单个空格（<code> </code>）字符表示）组合了两个选择器，如果第二个选择器匹配的元素具有与第一个选择器匹配的祖先（父母，父母的父母，父母的父母的父母等）元素，则它们将被选择。利用后代组合器的选择器称为后代选择器。</p>
<p>​    简单来说，就是，第二个元素是第一个元素的后代，但是可以不是直接后代。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">.a .c &#123; ... &#125;</span><br><span class="line"></span><br><span class="line">&lt;div class=&quot;a&quot;&gt;</span><br><span class="line">  &lt;div&gt;</span><br><span class="line">    &lt;div class=&quot;c&quot;&gt;&lt;/div&gt;</span><br><span class="line">  &lt;/div&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line">如同上面这样，a存在后代c，但是不是直接后代，可以使用后代选择器(` `), 而不能使用子选择器(`&gt;`)</span><br></pre></td></tr></table></figure>



<h2 id="通用兄弟选择器"><a href="#通用兄弟选择器" class="headerlink" title="通用兄弟选择器"></a>通用兄弟选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/General_sibling_combinator</span><br></pre></td></tr></table></figure>

<p>​        兄弟选择符，位置无须紧邻，只须同层级，<code>A~B</code> 选择<code>A</code>元素之后所有同层级<code>B</code>元素。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ele1 ~ ele2 &#123; ... &#125;</span><br></pre></td></tr></table></figure>



<h2 id="ID-选择器"><a href="#ID-选择器" class="headerlink" title="ID 选择器"></a>ID 选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/ID_selectors</span><br></pre></td></tr></table></figure>

<p>​        CSS ID 选择器会根据该元素的 ID 属性中的内容匹配元素,元素 ID 属性名必须与选择器中的 ID 属性名完全匹配，此条样式声明才会生效。</p>
<p><strong>注：</strong></p>
<p>​    一般一个html里面，一个id只能一个，如果有多个，那么这个就会选中多个。</p>
<p>​    id属性的值只有一个，不像使用class属性那样，可以有空格划分</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#id &#123; ... &#125;</span><br><span class="line"></span><br><span class="line">同属性选择器的</span><br><span class="line">[id=value] &#123; ... &#125;</span><br></pre></td></tr></table></figure>



<h2 id="选择器列表"><a href="#选择器列表" class="headerlink" title="选择器列表"></a>选择器列表</h2><p>选择器分组</p>
<p>​        CSS <strong>选择器列表</strong>（<code>,</code>），常被称为并集选择器或并集组合器，选择所有能被列表中的任意一个选择器选中的节点。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">h1,</span><br><span class="line">#id,</span><br><span class="line">.class,</span><br><span class="line">.a &gt; span &#123;</span><br><span class="line">	...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>注意点：</strong></p>
<p>​        选择器列表无效化，说的是当一个选择器不被支持，就会出现整条规则全部失效，我这里看了一个人写的，<a target="_blank" rel="noopener" href="https://www.xinran001.com/frontend/248.html">出现无效的伪选择器</a> 他的说明是如果是一个伪选择器无效的话，就会出现这个问题。但是如果是一个选择器的写法满足一个浏览器的cssom的构建，那么就不会出现这个问题。</p>
<p>​            解决这个问题的一个方法是使用 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/:is"><code>:is()</code></a> 选择器，它会忽视它的参数列表中失效的选择器，但是由于 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/:is"><code>:is()</code></a> 会影响优先级的计算方式，这么做的代价是，其中的所有选择器都会拥有相同的优先级。</p>
<h2 id="元素选择器"><a href="#元素选择器" class="headerlink" title="元素选择器"></a>元素选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Type_selectors</span><br></pre></td></tr></table></figure>

<p>​        CSS元素选择器(也称为类型选择器)通过node节点名称匹配元素.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ele &#123; ... &#125;</span><br><span class="line"></span><br><span class="line">span &#123; ... &#125;</span><br></pre></td></tr></table></figure>



<h2 id="通配选择器"><a href="#通配选择器" class="headerlink" title="通配选择器"></a>通配选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Universal_selectors</span><br></pre></td></tr></table></figure>

<p>​        在CSS中,一个星号(<code>*</code>)就是一个通配选择器.它可以匹配任意类型的HTML元素</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">* &#123; ... &#125;</span><br></pre></td></tr></table></figure>

<p>​        CSS3里面，*可以和命名空间搭配使用，命名空间，我现在也没有了解，我们后面在学。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ns|* - 会匹配ns命名空间下的所有元素</span><br><span class="line">*|* - 会匹配所有命名空间下的所有元素</span><br><span class="line">|* - 会匹配所有没有命名空间的元素</span><br></pre></td></tr></table></figure>



<h2 id="伪类选择器"><a href="#伪类选择器" class="headerlink" title="伪类选择器"></a>伪类选择器</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Pseudo-classes</span><br></pre></td></tr></table></figure>

<h3 id="常用的"><a href="#常用的" class="headerlink" title="常用的"></a>常用的</h3><p><strong>active</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a:active </span><br><span class="line">可以代表按下按键和松开按键。常用于按钮和链接</span><br></pre></td></tr></table></figure>

<p><strong>focus</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">获得焦点时</span><br></pre></td></tr></table></figure>

<p><strong>hover</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">鼠标放在上面时触发</span><br></pre></td></tr></table></figure>

<p>MDN上有个描述</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">:hover CSS伪类适用于用户使用指示设备虚指一个元素（没有激活它）的情况。这个样式会被任何与链接相关的伪类重写，像:link, :visited, 和 :active等。为了确保生效，:hover规则需要放在:link和:visited规则之后，但是在:active规则之前，按照LVHA的循顺序声明:link－:visited－:hover－:active。</span><br><span class="line"></span><br><span class="line">大致意思就是说， link会覆盖掉其他的样式，如果写在后面，其他的样式不会显示出来。</span><br></pre></td></tr></table></figure>

<p><strong>link</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">应该只能用于 a 标签，我使用span标签没有成功</span><br><span class="line">:link伪类选择器是用来选中元素当中的链接，所有未访问的链接（如果定义了visited伪元素），但是如果没有定义visited伪元素的话，那么就会将所有链接都选中，不管是不是访问过的。</span><br><span class="line">对于一个链接是否访问过，应该是通过href的值来进行的判断。</span><br><span class="line">因为link会覆盖其他伪元素的样式，所以书写顺序是：</span><br><span class="line">	:link — :visited — :hover — :active。:focus伪类选择器常伴随在:hover伪类选择器左右，需要根据你想要实现的效果确定它们的顺序。</span><br></pre></td></tr></table></figure>



<p><strong>disabled</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">表示被禁用的元素</span><br></pre></td></tr></table></figure>

<p><strong>enabled</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">没有被禁用的元素</span><br></pre></td></tr></table></figure>



<p><strong>invalid</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:invalid CSS 伪类 表示任意内容未通过验证的 &lt;input&gt; 或其他 &lt;form&gt; 元素 .</span><br></pre></td></tr></table></figure>

<p><strong>valid</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">:valid CSS 伪类表示内容验证正确的&lt;input&gt; 或其他 &lt;form&gt; 元素。这能简单地将校验字段展示为一种能让用户辨别出其输入数据的正确性的样式。</span><br><span class="line"></span><br><span class="line">验证正确的展示</span><br></pre></td></tr></table></figure>

<p><strong>optional</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">:optional</span><br><span class="line">表示 任意没有 required 属性的  &lt;input&gt;，&lt;select&gt; 或  &lt;textarea&gt; 元素</span><br></pre></td></tr></table></figure>

<p><strong>required</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">:required</span><br><span class="line">表示设置了 required 属性的 &lt;input&gt;，&lt;select&gt; 或  &lt;textarea&gt; 元素</span><br></pre></td></tr></table></figure>

<p><strong>read-only</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">:read-only</span><br><span class="line">	选中其中元素不可被用户编辑的状态</span><br><span class="line">与之对应的</span><br><span class="line">	read-write</span><br></pre></td></tr></table></figure>



<p><strong>first-child</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">一组兄弟元素中的第一个元素。</span><br><span class="line"></span><br><span class="line">p:first-child，代表的是p的第一个</span><br></pre></td></tr></table></figure>

<p><strong>last-child</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">一组兄弟元素中的最后一个元素。</span><br></pre></td></tr></table></figure>

<p><strong>not</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">反选</span><br><span class="line"></span><br><span class="line">:not(p)</span><br><span class="line">不要p标签的</span><br></pre></td></tr></table></figure>

<p><strong>nth-child</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">:nth-child(an+b) 这个 CSS 伪类首先找到所有当前元素的兄弟元素，然后按照位置先后顺序从1开始排序，选择的结果为CSS伪类:nth-child括号中表达式（an+b）匹配到的元素集合（n=0，1，2，3...）。</span><br><span class="line"></span><br><span class="line">简单来说，:nth-child(an+b)，其中 an+b 的值的范围是 1~n，超过范围的不会显示，虽然 an+b 的范围是 1~n，但是n的范围却是 0~，因为我们使用 n+1 可以发现，每个都还是有，说明了这个事实。</span><br><span class="line"></span><br><span class="line">几个特殊值：使用后，不要再加n和b了</span><br><span class="line">	odd，奇数行</span><br><span class="line">	even，偶数行</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong></p>
<p>​    不能写成 b+an 的形式，只能是 an+b</p>
<p>​    可以使用减号，<code>-</code>, 但是要注意一个问题，就是n的取值，貌似不是从 0~n，而是从0开始，不知道最终值是多少，所以对于 :nth-child(n-10)，还是会全部显示，但是使用 :nth-child(2n - 1)，就会发现不同。</p>
<p>​    所以一般要找前面n个，都是使用的 <code>-n+b</code>。</p>
<p>​    第二个不能使用n  2n-n，没有效果。</p>
<p><strong>nth-last-child</strong></p>
<p>​    从兄弟节点中从后往前匹配处于某些位置的元素</p>
<p><strong>注意:</strong> 这个伪类和 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/:nth-child"><code>:nth-child</code></a> 基本一致, 但它是从<em>结尾</em>计数, 而不是从开始计数.</p>
<p><strong>only-child</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">匹配没有任何兄弟的元素</span><br><span class="line"></span><br><span class="line">.b</span><br><span class="line">	.c</span><br><span class="line">	.c</span><br><span class="line">.b</span><br><span class="line">	.c</span><br><span class="line">	</span><br><span class="line">	类似于上面的，不是通过 .b:only-child，因为在同层中，.b没有只存在一个的情况，使用 .c:only-child 就能找到。</span><br><span class="line"></span><br><span class="line">	等效的选择器还可以写成 :first-child:last-child或者:nth-child(1):nth-last-child(1),当然,前者的权重会低一点.</span><br></pre></td></tr></table></figure>



<p><strong>root</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:root 这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说，:root 表示 &lt;html&gt; 元素，除了优先级更高之外，与 html 选择器相同。</span><br></pre></td></tr></table></figure>

<p><strong>target</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">对目标元素的id进行一个匹配，当url中出现了这个id时显示，url的构造形式类似于vue-router 的hash模式</span><br><span class="line"></span><br><span class="line">&lt;div id=&quot;12&quot;&gt;&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">div:target &#123; &#125; </span><br><span class="line">当url为 http://xxxx#12 时，这里面的效果就会展示出来</span><br></pre></td></tr></table></figure>



<h1 id="选择器优先级"><a href="#选择器优先级" class="headerlink" title="选择器优先级"></a>选择器优先级</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity</span><br></pre></td></tr></table></figure>

<p>简单来说，</p>
<p><strong>!important &gt; 行内样式&gt;ID选择器 &gt; 类选择器 &gt; 标签 &gt; 通配符 &gt; 继承 &gt; 浏览器默认属性</strong></p>
<p>我们是使用的权重方式进行的判断优先级</p>
<p><strong>内联的权重是：1 0 0 0</strong></p>
<p><strong>id的权重是 1 0 0</strong></p>
<p><strong>class的权重是 1 0</strong></p>
<p><strong>标签的权重是 1</strong></p>
<p><strong>注意：</strong></p>
<p>​    权重是不会进位的，不会因为有11个class，就可以超过id</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/25/JavaScript/%E6%96%B9%E6%B3%95/JavaScript-parseInt%E5%87%BD%E6%95%B0/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/25/JavaScript/%E6%96%B9%E6%B3%95/JavaScript-parseInt%E5%87%BD%E6%95%B0/" class="post-title-link" itemprop="url">JavaScript-parseInt函数</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-25 19:41:27" itemprop="dateCreated datePublished" datetime="2021-10-25T19:41:27+08:00">2021-10-25</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/Global-Objects/" itemprop="url" rel="index"><span itemprop="name">Global_Objects</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="parseInt函数"><a href="#parseInt函数" class="headerlink" title="parseInt函数"></a>parseInt函数</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseInt</span><br></pre></td></tr></table></figure>

<p>​    <strong>parseInt(*string*, *radix*)</strong>  解析一个字符串并返回指定基数的十进制整数， <code>radix</code> 是2-36之间的整数，表示被解析字符串的基数。</p>
<h2 id="参数解析"><a href="#参数解析" class="headerlink" title="参数解析"></a>参数解析</h2><p><strong>string</strong></p>
<p>​        要被解析的值。如果参数不是一个字符串，则将其转换为字符串(使用  <code>ToString </code>抽象操作)。字符串开头的空白符将会被忽略。</p>
<p><strong>radix</strong></p>
<p>​        从 <code>2</code> 到 <code>36</code>，表示字符串的基数。例如指定 16 表示被解析值是十六进制数。请注意，10不是默认值！简单来说就是设置进制，一个2~36的进制</p>
<h2 id="返回值"><a href="#返回值" class="headerlink" title="返回值"></a>返回值</h2><p>一个整数，</p>
<p>或者NaN</p>
<p>​    转换NaN的情况</p>
<p>​        <code>radix</code> 小于 <code>2</code> 或大于 <code>36</code> ，或</p>
<p>​        第一个非空格字符不能转换为数字。</p>
<p><strong>注意：</strong></p>
<p>​    这个在进行进制运算时，不是先转为十进制在运算，而是直接进行对应的进制转换，</p>
<p>​        比如：    33 ， 2 此时是：33转为2进制的转换，因为2进制每位数最大值是1，所以33直接NaN，但是如果是12，就会转化为1.</p>
<h2 id="面试问到的："><a href="#面试问到的：" class="headerlink" title="面试问到的："></a>面试问到的：</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">const arr = [1, 2, 3, 10, 111];</span><br><span class="line">arr.map(parseInt)</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">简单的解析一下，</span><br><span class="line">首先map内部的回调函数的三个参数分别为 value，index，array</span><br><span class="line">然后parseInt会使用两个参数，一个是要转换的字符串，一个是进制</span><br><span class="line">所以 按照顺序就会变成： 1,0	2,1		3,2		10,3	111,4</span><br><span class="line">	对于0，会使用默认形式，对于1，会直接NaN，对于后面的就按照正常进制的运算</span><br><span class="line">	所以结果是： 1,NaN,NaN,3,21</span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/25/JavaScript/%E6%96%B9%E6%B3%95/JavaScript-map%E5%87%BD%E6%95%B0/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/25/JavaScript/%E6%96%B9%E6%B3%95/JavaScript-map%E5%87%BD%E6%95%B0/" class="post-title-link" itemprop="url">JavaScript-map函数</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-25 16:48:23" itemprop="dateCreated datePublished" datetime="2021-10-25T16:48:23+08:00">2021-10-25</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/Array/" itemprop="url" rel="index"><span itemprop="name">Array</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="JavaScript之Array-map函数"><a href="#JavaScript之Array-map函数" class="headerlink" title="JavaScript之Array.map函数"></a>JavaScript之Array.map函数</h1><h2 id="使用方法"><a href="#使用方法" class="headerlink" title="使用方法"></a>使用方法</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map</span><br></pre></td></tr></table></figure>

<p><code>**map()**</code> 方法创建一个新数组，其结果是该数组中的每个元素是调用一次提供的函数后的返回值。</p>
<p><strong>参数</strong></p>
<p>​    <strong>回调函数，callback</strong></p>
<p>​        参数分别为，value，index，array，第二个和第三个参数是可选的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">const array1 = [1, 4, 9, 16];</span><br><span class="line"></span><br><span class="line">// pass a function to map</span><br><span class="line">const map1 = array1.map(x =&gt; x * 2);</span><br><span class="line"></span><br><span class="line">console.log(map1);</span><br><span class="line">// expected output: Array [2, 8, 18, 32]</span><br></pre></td></tr></table></figure>

<p>​    <strong>thisArg</strong></p>
<p>​        在执行callabck函数时，被用作 <code>this</code></p>
<h2 id="简单的源码实现"><a href="#简单的源码实现" class="headerlink" title="简单的源码实现"></a>简单的源码实现</h2><p>通过上面的参数描述，我们可以知道，</p>
<p>我们需要先对数组进行循环，然后将其带入callback，返回值会push入一个res数组，</p>
<p>然后因为第二个参数是this的指向，所以我们需要在判断是否携带了第二个参数**(  const _this = thisArg || this;)**</p>
<p>将其this的指向进行改变，使用了call方法。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">function myMap(callback, thisArg) &#123;</span><br><span class="line">  const result = [];</span><br><span class="line">  const arr = this;</span><br><span class="line">  const _this = thisArg || this;</span><br><span class="line"></span><br><span class="line">  for (let i = 0; i &lt; arr.length; i++) &#123;</span><br><span class="line">    result.push(callback.call(_this, arr[i], i, arr));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  return result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="一些面试时遇到的问题"><a href="#一些面试时遇到的问题" class="headerlink" title="一些面试时遇到的问题"></a>一些面试时遇到的问题</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">const arr = [1, 2, 3, 10, 111];</span><br><span class="line"></span><br><span class="line">arr.map(parseInt)</span><br><span class="line"></span><br><span class="line">这个可能有的没有理解的话会有点懵逼</span><br><span class="line">其实理解了就很简单了。</span><br><span class="line">这就是把parseInt作为一个回调函数传递给了map，</span><br><span class="line">map的回调函数的参数是，value， index， arr</span><br><span class="line">而parseInt，可以带两个参数，这两个参数，一个是要转化的字符串（数字也可以），一个是要转化的进制。</span><br><span class="line"></span><br><span class="line">所以我们就能够理解了，</span><br><span class="line">对于 arr 1， 2， 3， 10， 111</span><br><span class="line">会分别传递</span><br><span class="line">	1， 0</span><br><span class="line">	2， 1</span><br><span class="line">	3， 2</span><br><span class="line">	10， 3</span><br><span class="line">	111， 4</span><br><span class="line">其中，0代表了默认转换，对于字符串没有进制前缀的，就是默认十进制，具体的转换规则后续写 parseInt 的时候再说明。</span><br><span class="line"></span><br><span class="line">我们可以看出，1对应的默认进制转换，2对应的1进制，3对应的2进制，10对应的3进制，111对应的4进制，因为parseInt的第二个参数范围是2-36，所以对于其他的除0以外直接NaN。</span><br><span class="line">所以对应的结果是 1, NaN, NaN, 3, 21.</span><br></pre></td></tr></table></figure>

<p>对于其他的就也可以按照这个思路进行思考了。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/10/24/CSS/border-radius%E7%9A%84%E5%8E%9F%E7%90%86%E5%92%8C%E4%BD%BF%E7%94%A8/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/10/24/CSS/border-radius%E7%9A%84%E5%8E%9F%E7%90%86%E5%92%8C%E4%BD%BF%E7%94%A8/" class="post-title-link" itemprop="url">border-radius的原理和使用</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-10-24 10:53:12" itemprop="dateCreated datePublished" datetime="2021-10-24T10:53:12+08:00">2021-10-24</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/CSS/" itemprop="url" rel="index"><span itemprop="name">CSS</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="border-radius的原理和使用"><a href="#border-radius的原理和使用" class="headerlink" title="border-radius的原理和使用"></a>border-radius的原理和使用</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/border-radius</span><br></pre></td></tr></table></figure>



<h2 id="原理："><a href="#原理：" class="headerlink" title="原理："></a>原理：</h2><p>首先我们可以知道 <code>border-radius</code> 是四个属性的简写，所以我们先理解四个属性的值的效果。</p>
<p><code>border-top-right-radius</code> <code>border-top-left-radius</code></p>
<p> <code>border-bottom-right-radius</code> <code>border-bottm-left-radius</code></p>
<p>我们取其中一个</p>
<p><code>border-top-right-radius</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/CSS/border-top-right-radius</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">border-top-right-radius属性设置元素的右上角弧形，这个圆弧可能是一个椭圆，或者其中一个值是0的话，就是没有圆弧，换句话就是说拐角是方形的。</span><br></pre></td></tr></table></figure>

<img src="/.io//image-20211025104917514.png" alt="image-20211025104917514" style="zoom:50%;">

<p>通过图片我们可以知道 <code>border-top-right-radius</code> 的值是一个据 top 和 right 的一个半径，然后画弧所裁剪出来的值。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">border-top-right-radius: radius               </span><br><span class="line">/* the corner is a circle    */  E.g. border-top-right-radius: 3px</span><br><span class="line">border-top-right-radius: horizontal vertical  </span><br><span class="line">/* the corner is an ellipsis */  E.g. border-top-right-radius: 0.5em 1em</span><br></pre></td></tr></table></figure>

<p>通过例子也可以知道，对于一个值，说明了 横轴<code>horizontal</code> 和 数轴<code>vertical</code> 的值相等，对于两个值，那么就说明了第一值是横轴，第二个值是数轴。</p>
<p>然后得到横轴和数轴的半径后，相对进行偏移，然后画出一个圆形或者一个椭圆形，所裁剪出来的值。就是得到的效果。</p>
<p>对于值是%的，那么宽度就会相对于宽度，高度就会相对于高度。</p>
<h3 id="对于超过-50-的计算方式"><a href="#对于超过-50-的计算方式" class="headerlink" title="对于超过 50% 的计算方式"></a>对于超过 50% 的计算方式</h3><p>原文链接</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://zhuanlan.zhihu.com/p/20128284</span><br></pre></td></tr></table></figure>

<p>简单来说就是对于 <strong>相邻的角的半径和超过了对应的盒子的边的长度，那么浏览器要重新计算保证它们不会重合。</strong></p>
<p>就是会同时进行缩放。来保证不会重合。</p>
<h2 id="水平和垂直从哪个位置开始偏移"><a href="#水平和垂直从哪个位置开始偏移" class="headerlink" title="水平和垂直从哪个位置开始偏移"></a>水平和垂直从哪个位置开始偏移</h2><h3 id="我们先看使用px的计算"><a href="#我们先看使用px的计算" class="headerlink" title="我们先看使用px的计算"></a>我们先看使用px的计算</h3><p>先说结果，结果是，<strong>px的计算是相对于border的位置开始的偏移。</strong></p>
<p>然后我们再看代码和执行结果</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html lang=&quot;zh&quot;&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">  &lt;meta charset=&quot;UTF-8&quot;&gt;</span><br><span class="line">  &lt;title&gt;Title&lt;/title&gt;</span><br><span class="line">  &lt;style&gt;</span><br><span class="line">    .d &#123;</span><br><span class="line">      width: 100px;</span><br><span class="line">      height: 100px;</span><br><span class="line">      background-color: #f00;</span><br><span class="line">      border: blue solid 10px;</span><br><span class="line">      padding: 10px;</span><br><span class="line">      margin: 10px;</span><br><span class="line">      border-radius: 10px;</span><br><span class="line">    &#125;</span><br><span class="line">  &lt;/style&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">&lt;div class=&quot;d&quot;&gt;123&lt;/div&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>

<img src="/.io//image-20211025104342522.png" alt="image-20211025104342522" style="zoom:50%;">



<h3 id="我们再看使用-百分号-进行的计算"><a href="#我们再看使用-百分号-进行的计算" class="headerlink" title="我们再看使用 百分号% 进行的计算"></a>我们再看使用 百分号% 进行的计算</h3><p>意思是一样的，会按照你的宽高加上你的border的宽高，然后乘以 百分比。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">开始我这样写，以为10%应该是 50px，但是忘了border有上有下，所以真正的宽高是550px，所以50%是55px，后面才搞清楚</span><br><span class="line"></span><br><span class="line">width: 450px;</span><br><span class="line">height: 450px;</span><br><span class="line">background-color: #f00;</span><br><span class="line">border: blue solid 50px;</span><br><span class="line">border-radius: 10%;</span><br></pre></td></tr></table></figure>



<h2 id="如何裁剪"><a href="#如何裁剪" class="headerlink" title="如何裁剪"></a>如何裁剪</h2><p>这个就是自己的理解了，我们可以看到，对于存在了border的，当你的数值超过了一定值之后，你的content也会变成弧边，而这个值就是border的宽度。</p>
<p><strong>所以这个裁剪的方法是：</strong></p>
<ul>
<li><p>先计算出radius的偏移量x，y</p>
</li>
<li><p>然后从border的边框开始进行x，y的偏移，并且半径值也为x，y画弧，将border进行了裁剪。</p>
</li>
<li><p>然后如果x，y的偏移量在content里面了（这个content是包含了padding的），那么就会再对content进行裁剪，而裁剪的半径就是x，y这个点到content边界的半径。</p>
</li>
</ul>
<p>示例：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html lang=&quot;zh&quot;&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">  &lt;meta charset=&quot;UTF-8&quot;&gt;</span><br><span class="line">  &lt;title&gt;Title&lt;/title&gt;</span><br><span class="line">  &lt;style&gt;</span><br><span class="line">    * &#123;</span><br><span class="line">      padding: 0;</span><br><span class="line">      margin: 0;</span><br><span class="line">    &#125;</span><br><span class="line">    .d &#123;</span><br><span class="line">      width: 450px;</span><br><span class="line">      height: 450px;</span><br><span class="line">      background-color: #f00;</span><br><span class="line">      border: blue solid 25px;</span><br><span class="line">      border-top: blue solid 30px;</span><br><span class="line">      border-left: blue solid 10px;</span><br><span class="line">      padding: 50px;</span><br><span class="line">      margin: 10px;</span><br><span class="line">      border-top-left-radius: 30px 40px;</span><br><span class="line">    &#125;</span><br><span class="line">  &lt;/style&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">&lt;div class=&quot;d&quot;&gt;123&lt;/div&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>

<p>结果：</p>
<img src="/.io//image-20211025155459099.png" alt="image-20211025155459099" style="zoom:67%;">



<h2 id="简写参数"><a href="#简写参数" class="headerlink" title="简写参数"></a>简写参数</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">border-radius: top-left top-right bottom-right bottom-left;</span><br><span class="line">上左，上右，下右，下左，这是一个从上左开始的一个顺时针顺序。</span><br><span class="line">按此顺序设置每个 radii 的四个值。如果省略 bottom-left，则与 top-right 相同。如果省略 bottom-right，则与 top-left 相同。如果省略 top-right，则与 top-left 相同。</span><br><span class="line">	参考链接：(https://www.w3school.com.cn/cssref/pr_border-radius.asp)</span><br><span class="line">意思就是，如果在省略的情况下，那么就是最后一个开始是没有值的，而前面的才有值，然后对没有值的那个，他的值就是对面的值，如果对面也没有值，那么他的值就和旁边的相等(此时就是只有一个参数)</span><br><span class="line"></span><br><span class="line">按照上面的意思来理解的话，那么很多简写参数都可以理解了。我这里就直接统计结果。</span><br></pre></td></tr></table></figure>



<h3 id="第一步，将参数从简写的个数化为完整个数"><a href="#第一步，将参数从简写的个数化为完整个数" class="headerlink" title="第一步，将参数从简写的个数化为完整个数"></a>第一步，将参数从简写的个数化为完整个数</h3><h4 id="一个参数-border-radius-50px"><a href="#一个参数-border-radius-50px" class="headerlink" title="一个参数 border-radius: 50px;"></a>一个参数 <code>border-radius: 50px;</code></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">border-radius: 50px;</span><br><span class="line"></span><br><span class="line">只有一个 top-left </span><br><span class="line">那么，bottom-right = top-left = 50</span><br><span class="line">并且 bottom-left = top-right = top-left = 50</span><br><span class="line"></span><br><span class="line">border-radius: 50px 50px 50px 50px;</span><br></pre></td></tr></table></figure>



<h4 id="两个参数-border-radius-50px-30px"><a href="#两个参数-border-radius-50px-30px" class="headerlink" title="两个参数 border-radius: 50px 30px;"></a>两个参数 <code>border-radius: 50px 30px;</code></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">border-radius: 50px 30px;</span><br><span class="line"></span><br><span class="line">有两个，那么这两个就是 top-left 和 top-right</span><br><span class="line">对应的 bottom-left = top-right = 30</span><br><span class="line">bottom-right = top-left = 50</span><br><span class="line"></span><br><span class="line">border-radius: 50px 30px 50px 30px;</span><br></pre></td></tr></table></figure>



<h4 id="三个参数-border-radius-50px-30px-40px"><a href="#三个参数-border-radius-50px-30px-40px" class="headerlink" title="三个参数 border-radius: 50px 30px 40px;"></a>三个参数 <code>border-radius: 50px 30px 40px;</code></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">border-radius: 50px 30px 40px;</span><br><span class="line"></span><br><span class="line">有三个，那么就只有最后一个 bottom-left 没有</span><br><span class="line">那么 bottom-left 等于对面的 top-right = 30px</span><br><span class="line"></span><br><span class="line">border-radius: 50px 30px 40px 30px;</span><br></pre></td></tr></table></figure>



<h4 id="四个参数-border-radius-50px-40px-30px-20px"><a href="#四个参数-border-radius-50px-40px-30px-20px" class="headerlink" title="四个参数 border-radius: 50px 40px 30px 20px;"></a>四个参数 <code>border-radius: 50px 40px 30px 20px;</code></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">border-radius: 50px 40px 30px 20px;</span><br><span class="line"></span><br><span class="line">没啥说的。</span><br></pre></td></tr></table></figure>



<h4 id="对于参数里面带有-符号的-border-radius-4px-3px-6px-2px-4px"><a href="#对于参数里面带有-符号的-border-radius-4px-3px-6px-2px-4px" class="headerlink" title="对于参数里面带有 / 符号的 border-radius: 4px 3px 6px / 2px 4px;"></a>对于参数里面带有 <code>/</code> 符号的 <code>border-radius: 4px 3px 6px / 2px 4px;</code></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">border-radius: 4px 3px 6px / 2px 4px;</span><br><span class="line"></span><br><span class="line">这个分为两个部分</span><br><span class="line">第一部分 4 3 6 将其转化为对应的 horizontal</span><br><span class="line">	所以为 4 3 6 3</span><br><span class="line">第二部分 2 4 将其转化为对应的 vertical</span><br><span class="line">	所以为 2 4 2 4</span><br><span class="line">	</span><br><span class="line">border-radius: 4px 3px 6px 3px / 2px 4px 2px 4px;</span><br><span class="line">	</span><br><span class="line">然后结果就是</span><br><span class="line">border-top-left-radius:     4px 2px;</span><br><span class="line">border-top-right-radius:    3px 4px;</span><br><span class="line">border-bottom-right-radius: 6px 2px;</span><br><span class="line">border-bottom-left-radius:  3px 4px;</span><br></pre></td></tr></table></figure>



<h3 id="第二步，将其转化为-border-radius"><a href="#第二步，将其转化为-border-radius" class="headerlink" title="第二步，将其转化为 border-*-*-radius"></a>第二步，将其转化为 <code>border-*-*-radius</code></h3><h4 id="对于没有带-符号的-border-radius-50px-40px-30px-20px"><a href="#对于没有带-符号的-border-radius-50px-40px-30px-20px" class="headerlink" title="对于没有带 / 符号的 border-radius: 50px 40px 30px 20px;"></a>对于没有带 <code>/</code> 符号的 <code>border-radius: 50px 40px 30px 20px;</code></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">其 horizontal 和 vertical 的值相等。</span><br><span class="line"></span><br><span class="line">border-radius: 50px 40px 30px 20px;</span><br><span class="line"></span><br><span class="line">border-top-left-radius:     50px 50px;</span><br><span class="line">border-top-right-radius:    40px 40px;</span><br><span class="line">border-bottom-right-radius: 30px 30px;</span><br><span class="line">border-bottom-left-radius:  20px 20px;</span><br></pre></td></tr></table></figure>



<h4 id="对于带有-符号的-border-radius-4px-3px-6px-3px-2px-4px-2px-4px"><a href="#对于带有-符号的-border-radius-4px-3px-6px-3px-2px-4px-2px-4px" class="headerlink" title="对于带有 / 符号的 border-radius: 4px 3px 6px 3px / 2px 4px 2px 4px;"></a>对于带有 <code>/</code> 符号的 <code>border-radius: 4px 3px 6px 3px / 2px 4px 2px 4px;</code></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">会将 / 前的作为每一个的 horizontal </span><br><span class="line">/ 后的作为每一个的 vertical</span><br><span class="line"></span><br><span class="line">border-radius: 4px 3px 6px 3px / 2px 4px 2px 4px;</span><br><span class="line"></span><br><span class="line">border-top-left-radius:     4px 2px;</span><br><span class="line">border-top-right-radius:    3px 4px;</span><br><span class="line">border-bottom-right-radius: 6px 2px;</span><br><span class="line">border-bottom-left-radius:  3px 4px;</span><br></pre></td></tr></table></figure>




      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/8/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/8/">8</a><span class="page-number current">9</span><a class="page-number" href="/page/10/">10</a><a class="page-number" href="/page/11/">11</a><a class="extend next" rel="next" href="/page/10/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
  </nav>

</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">tallgy</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  





  





</body>
</html>
